Replace version number in file with sed in Bash script - linux

In my project.pro file I have:
DEFINES += VERSION=\\\"1.13.1\\\"
I'd like to replace whatever the current version number is, with a new one in a Bash script:
VERSION_MAJOR=1
VERSION_MINOR=14
VERSION_PATCH=1
sed -i "s/\([0-9]+.[0-9]+.[0-9]+\)/\1${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}/" project.pro
Why is that not working?
So far I have managed to get either no matches at all or then some weird replace-only-the-last-number substitutions.

You may use this sed:
sed -i.bak -E "s/[0-9]+\.[0-9]+\.[0-9]+/$VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH/" project.pro
Few problems in your attempt:
Without extended regex mode (-E), + cannot be used unescaped.
dot needs to be escaped in a regex
No need to use a capture group and back-reference \1.
PS: .bak is extension of backup file so that you can get original file, in case of a wrong substitution.

Related

regex replace in linux for multiple files

I have 200k files in a single folder in linux server where i need to transform this files using regex
here is the regex to find in text file
([^\s]+?.*)=((.*(?=,$))+|.*).*
now I need to replace it with below substitution value
"$1":"$2",
the above regex is working fine when i used them in python. the server which i am working does not
support python, so i need to use bash commands. i have tried below bash command but it is not working
command:
sed -r 's/([^\s]+?.*)=((.*(?=,$))+|.*).*/"$1":"$2",/g' *20200502*
the above bash command is not working
Fixed your regex:
sed -E 's/([^[:space:]]+?.*)=((.*(=?,$))+|.*).*/"\1":"\2",/g' *20200502*
Replaced inappropriate [^\s] by its POSIX ERE syntax equivalent [^[:space:]].
Fixed the misplaced optional marker ?=,$ with =?,$ instead.
Fixed the invalid capture group reference syntax "$1":"$2" with "\1":"\2".
Kinda difficult to test but just analyzing your approach this might work:
sed -i -E "s/([^\s]+?.*)=((.*(?=,$))+|.*).*/\1$1\2$2/" *20200502*
\1 and \2 in the second part are references to the groups captured in the first part
-E for extended regular expressions (+ and grouping)

Sed how to find and replace a value using a bash variable [duplicate]

I have a configuration file (gpsd.default) containing data with the following format:
# If you must specify a non-NMEA driver, uncomment and modify the next line
GPSD_SOCKET="/var/run/gpsd.sock"
GPSD_OPTIONS=""
GPS_DEVICES=""
I am making a change on the file with sed:
sed -i 's/^GPS_DEVICES="".*/GPS_DEVICES="dev/ttyUSB1"/' /etc/default/gpsd.default
or
sed -i '4s/^.*/GPS_DEVICES="dev/ttyUSB1"/' /etc/default/gpsd.default
The above sed command returns error:
sed: bad option in substitution expression
Because the new line contains "/" in its expression.
How to update my sed command to make it work?
This is because you are using a regex containing /, which is the same character sed uses as delimiter.
Just change the sed delimiter to another one, for example ~:
sed -i 's~^GPS_DEVICES="".*~GPS_DEVICES="dev/ttyUSB1"~' /etc/default/gpsd.default
By the way, since you are changing files in /etc, you may want to use -i.bak, so that the original file gets backed up. It is a good practice to prevent loss of important information.
You should update your sed command to this.
sed -i 's/^GPS_DEVICES=\"\".*/GPS_DEVICES=\"dev\/ttyUSB1\"/' /etc/default/gpsd.default

difficult string to replace in script using SED

I know, many people have had questions on how to use sed to replace a string, but I have a difficult one here.
I have a file I need to replace a string of text that prompts the user to enter content. I want to automate this so the user does not interact. By replacing this string with a static file path. but the text is a bash script and has ' and " within the string I want to replace. It does not work. Either because I have syntax errors in my formatting, or it simply is not possible to do this action with sed. Please advice!
Here is what I am attempting to do:
I want to replace this long string
read -e -p 'Enter path for Boot Partition : ' BOOTUSERFILEPATH
with a string that looks like this:
BOOTUSERFILEPATH=../board-support/prebuilt-images
My attempt:
sed -i "/read -e -p 'Enter path for Boot Partition : ' BOOTUSERFILEPATH/BOOTUSERFILEPATH="../board-support/prebuilt-images"" file_to_search.sh
Update: I fixed the syntax error, but file still is not updated with the new path information... :(
found the problem. the search was not finding the strings because of an extra space in my search command. It works now!
There are forward slashes in your string so one needs to use a different delmiter. Here I use '|' as the delimiter.
sed "s|read -e -p \'Enter path for Boot Partition : \' BOOTUSERFILEPATH|BOOTUSERFILEPATH=../board-support/prebuilt-images|g" oldfile > newfile
You may note that the -i option to sed which allows files to be edited in place is not a POSIX supported option.
However if you wish to use it:
sed -i "s|read -e -p \'Enter path for Boot Partition : \' BOOTUSERFILEPATH|BOOTUSERFILEPATH=../board-support/prebuilt-images|g" oldfile
You may find it easier to use a pattern with sed which matches part of this string and then replaces its entirety:
sed 's|read -e -p .* BOOTUSERFILEPATH|BOOTUSERFILEPATH=../board-support/prebuilt-images|g' filename > newfilename
From the POSIX specification page for sed:
s/BRE/replacement/flags
Substitute the replacement string for instances of the BRE in the pattern space. Any character other than <backslash> or <newline> can be used instead of a slash to delimit the BRE and the replacement.
You need to use an actual substitute command, and you need to avoid the slashes in the replacement text from confusing sed. Personally, I'd probably use:
sed -i.bak "s%^read .* BOOTUSERFILEPATH$%BOOTUSERFILEPATH=../board-support/prebuilt-images%" file_to_search.sh
or even more likely:
BOOTUSERFILEPATH="../board-support/prebuild-images"
sed -i.bak "s%^read .* BOOTUSERFILEPATH$%BOOTUSERFILEPATH=$BOOTUSERFILEPATH%" file_to_search.sh
The s%%% uses % instead of / to delimit the parts of the command. I cheated on the match pattern, working on the assumption that you don't have many similar lines in the file.

replace unknown line in file linux command

I am trying to change a line with a pattern in a textual file using Linux bash.
I tried the sed command:
sed -i 's/old/new/' < file.txt
The issue with this command line I have to specify the exact "old" word. I want to change thousands of files where the old word has a pattern like this: old1(, old2(,old3(,....old10000(
I would like to change the oldxxx( in all files to old1(
Any ideas how to do this?
You can use something like:
sed -i 's/old[0-9]\{1,\}(/old1(/' file.txt
This matches "old" followed by one or more digits and a "(" and replaces it with "old1(".
If your version of sed supports extended regular expressions, you can use:
sed -r -i 's/old[0-9]+\(/old1(/' file.txt
instead, which does the same thing. On some versions of sed, the -E switch is used instead of -r.
If you have more than one instance of the pattern "oldXX(" on the same line, you may also want to the g modifier (s/.../.../g) to do a global replacement.

How to search and replace text in a file from a shell script?

I'm trying to write a shell script that does a search and replace inside a configuration file upon start-up.
The string we're trying to replace is:
include /etc/nginx/https.include;
and we want to replace it with a commented version:
#include /etc/nginx/https.include;
The file that contains the string that we want to replace is:
/etc/nginx/app-servers.include
I'm not a Linux guru and can't seem to find the command to do this.
perl -p -i -e 's%^(include /etc/nginx/https.include;)$%#$1%' /etc/nginx/ap-servers.include
If the line might not end in the ;, use instead:
perl -p -i -e 's%^(include /etc/nginx/https.include;.*)$%#$1%' /etc/nginx/ap-servers.include
If you want to preserve the original file, add a backup extension after -i:
perl -p -i.bak -e 's%^(include /etc/nginx/https.include;)$%#$1%' /etc/nginx/ap-servers.include
Now, explaining. The -p flag means replace in-place. All lines of the file will be fed to the expression, and the result will be used as replacement. The -i flag indicates the extension of the backup file. By using it without anything, you prevent generation of backups. The -e tells Perl to get the following parameter as an expression to be executed.
Now, the expression is s%something%other%. I use % instead of the more traditional / to avoid having to escape the slashes of the path. I use parenthesis in the expression and $1 in the substituted expression for safety -- if you change one, the other will follow. Thus, %#$1% is actually the second % of s, followed by the desired #, $1 indicating the pattern inside parenthesis, and the last % of s.
HTH. HAND.
sed -i 's/foo/bar/g' config.txt
This replaces all instances of foo (case insensitive) with bar in the file config.txt
Check out sed:
sed -i -r 's|^(include /etc/nginx/https.include;)$|#\1|' /etc/nginx/app-servers.include
-i means do the substitution in-place and -r means to use extended regular expressions.
cd pathname
for y in `ls *`;
do sed "s/ABCD/DCBA/g" $y > temp; mv temp $y;
done
This script shold replace string ABCD to DCBA in all the files in pathname

Resources