How to use variables in 'sed' command? - bash

Tried with following code:
revision=(revision="5.0")
sed -i "s/revision="1.0"/${revision}/g" /File-path/composite.xml)
But In the file the contents of revision="1.0" is replaced by ${revision}

Need to quote: "
sed -i "s/revision=\"1.0\"/${revision}/g" /File-path/composite.xml

Some syntax errors:
-i switch tell sed to execute infile replacement.
(...) tell bash to store an array of variables.
leading ) seem wrong.
My purpose:
revision='revision="5.0"'
sed -e "s/revision=\"[0-9.]*\"/${revision}/g" /File-path/composite.xml
or if you want file /File-path/composite.xml to be modified:
sed -e "s/revision=\"[0-9.]*\"/${revision}/g" -i /File-path/composite.xml
or even:
sed -e "s/revision=\"[0-9.]*\"/${revision}/g" -i.bak /File-path/composite.xml

Related

looping the sed -i to delete.

I have a file called foo.file.
In it are many things. I wanted to get rid of two lines containing
these keywords. employee.csv and instrument.csv. The sed -I flag is powerful feature in sed command. I like it to use on edit files in place.
It works just fine when I use in in command line format
sed -i '/employee.csv/d' foo.file
but when I try to loop the keywords. It does not work.
for i in employee.csv instrument.csv ;
do
sed -i '/"$i"/d' foo.file ;
done
~
for i in "employee.csv" "instrument.csv"; do
sed -i '/'"$i"'/d' foo.file;
done
You can also use regular expressions with sed:
sed -ri '/(employee|instrument).csv/d' foo.file;
Using sed to make an in-place substitution change:
for i in employee.csv instrument.csv; do
do sed -i "s/$i//g" foo.file;
done

why does it work with sed -e but not with sed -i

I have this in a file
echo "[[z[z[[e" > toto_test.txt
i'm trying this and things are ok
sed -e 's,\],,g' -e 's,\[,,g' toto_test.txt
Doing this and suddenly, it is not working anymore
sed -i 's,\],,g' -i 's,\[,,g' toto_test.txt
I have this error
sed: impossible to read s,\[,,g: No such file or directory
Why and how can I overcome the thing?
Thanks.
try
sed -i -e 's,\],,g' -e 's,\[,,g' toto_test.txt
-i means inplace modification,
-e means expression.
once you understand this, it's easy to provide proper parameters.
You don't need 2 replacements. Just use it as:
sed -i.bak 's,[][],,g' toto_test.txt
so far as I know, -i can't be repeated. It expect an optional backup suffix for the file edited in place (mandatory on OS X).
Try
sed -i 's,\],,g; s,\[,,g' toto_test.txt
(wanted to make this a comment but I don't seem to be allowed to do so, so I made it an answer)

Replace entire lines in a .conf file

I have a situation where I want a bash script to replace an entire lines in a dnsmasq.conf
By default, lines are :
listen-address=192.168.42.1
dhcp-range=192.168.42.1,192.168.42.253,255.255.255.0,192.168.42.255,24h
dhcp-option=option:router,192.168.42.1
I implement :
new_ip=$1
broadcast=$2
base_ip=`echo $new_ip | cut -d"." -f1-3`
sed -i 's/^listen-address.*/listen-address=$new_ip/' /etc/dnsmasq.conf
sed -i 's/^dhcp-range.*/dhcp-range=$base_ip.1,$base_ip.254,255.255.255.0,$broadcast,24h/' /etc/dnsmasq.conf
sed -i 's/^dhcp-option.*/dhcp-option=option:router,$new_ip/' /etc/dnsmasq.conf
I am calling the bash as ./test.sh 172.24.239.40 172.24.239.255 and I obtain the following lines :
listen-address=$new_ip
dhcp-range=$base_ip.1,$base_ip.254,255.255.255.0,$broadcast,24h
dhcp-option=option:router,$new_ip
Is it possible to dissociate the parameter from text in sed command lines ?
You can use:
sed -i.bak -e "s/^listen-address.*/listen-address=$new_ip/" \
-e "s/^dhcp-range.*/dhcp-range=$base_ip.1,$base_ip.254,255.255.255.0,$broadcast,24h/" \
-e "s/^dhcp-option.*/dhcp-option=option:router,$new_ip/" /etc/dnsmasq.conf
i.e.
use of double quotes instead of single quotes to allow variables to expand
use of multiple substitute command in single sed instead of calling sed multiple times
use of -i.bak to keep original file safe with .bak extension
Use double quotes instead of single quotes when you have variables in sed:
sed -i "s/^listen-address.*/listen-address=$new_ip/" /etc/dnsmasq.conf
sed -i "s/^dhcp-range.*/dhcp-range=$base_ip.1,$base_ip.254,255.255.255.0,$broadcast,24h/" /etc/dnsmasq.conf
sed -i "s/^dhcp-option.*/dhcp-option=option:router,$new_ip/" /etc/dnsmasq.conf

BackSpace in .bash file

I work with .bash script and I try to remove lines from file
sed -e s/^DNS1.*/''/g -i $DNS_IP_CONFIG_FILE
but remains blank lines.I need baskspace in this code
sed -i '/^DNS1.*/d' $DNS_IP_CONFIG_FILE
sed -i -e '/^DNS1/d' "$DNS_IP_CONFIG_FILE"
sed -i -ne '/^DNS1.*/!p' $DNS_IP_CONFIG_FILE

Text substitution (reading from file and saving to the same file) on linux with sed

I want to read the file "teste", make some "find&replace" and overwrite "teste" with the results. The closer i got till now is:
$cat teste
I have to find something
This is hard to find...
Find it wright now!
$sed -n 's/find/replace/w teste1' teste
$cat teste1
I have to replace something
This is hard to replace...
If I try to save to the same file like this:
$sed -n 's/find/replace/w teste' teste
or:
$sed -n 's/find/replace/' teste > teste
The result will be a blank file...
I know I am missing something very stupid but any help will be welcome.
UPDATE: Based on the tips given by the folks and this link: http://idolinux.blogspot.com/2008/08/sed-in-place-edit.html here's my updated code:
sed -i -e 's/find/replace/g' teste
On Linux, sed -i is the way to go. sed isn't actually designed for in-place editing, though; historically, it's a filter, a program which edits a stream of data in a pipeline, and for this usage you would need to write to a temporary file and then rename it.
The reason you get an empty file is that the shell opens (and truncates) the file before running the command.
You want: sed -i 's/foo/bar/g' file
You want to use "sed -i". This updates in place.
In-place editing with perl
perl -pi -w -e 's/foo/bar/g;' file.txt
or
perl -pi -w -e 's/foo/bar/g;' files*
for many files
The ed solution is:
ed teste <<END
1,$s/find/replace/g
w
q
END
Or without the heredoc
printf "%s\n" '1,$s/find/replace/g' w q | ed teste
Actually, if you use -i flag, sed will copy the original line you edit.
So this might be a better way:
sed -i -e 's/old/new/g' -e '/new/d' file
There is a useful sponge command.
sponge soaks up all its input before opening the output file.
$cat test.txt | sed 's/find/replace/w' | sponge test.txt
Nothing worked for me on MacOS, but after some research I found this answer.
So the following works on MacOS:
sed -i '' -e 's/find/replace/g' teste
However, on Linux distro's (in my pipelines) the following worked and the above command throwed errors:
sed -i -e 's/find/replace/g' teste

Resources