looping the sed -i to delete. - bash

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

Related

sed doesn't catch all sets of doubles

I've writted a sed script to replace all ^^ with NULL. It seems though that sed is only catching a pair, but not including the second in that pair as it continues to search.
echo "^^^^" | sed 's/\^\^/\^NULL\^/g'
produces
^NULL^^NULL^
when it should produce
^NULL^NULL^NULL^
Try with a loop to apply your command again to modified pattern space:
echo "^^^^" | sed ':a;s/\^\^/\^NULL\^/;t a;'
To edit a file in place on OSX, try the -i flag and multiline command:
sed -i '' ':a
s/\^\^/\^NULL\^/
t a' file
With GNU sed:
sed -i ':a;s/\^\^/\^NULL\^/;t a;' file
or simply redirect the command to a temporary file before renaming it:
sed ':a;s/\^\^/\^NULL\^/;t a;' file > tmp && mv tmp file
I really like SLePort solution, but since it is not working for you, you can try with (tested on Linux, not Mac):
echo "^^^^" | sed 's/\^\^/\^NULL\^/g; s//\^NULL\^/g'
It is doing the same as the former solution, but explicitly, not looping with tags.
You can omit the pattern in the second command and sed will use the previous pattern.

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)

sed in-place command not deleting from file in bash

I have a bash script which checks for a string pattern in file and delete entire line i same file but somehow its not deleting the line and no throwing any error .same command from command prompt deletes from file .
#array has patterns
for k in "${patternarr[#]}
do
sed -i '/$k/d' file.txt
done
sed version is >4
when this loop completes i want all lines matching string pattern in array to be deleted from file.txt
when i run sed -i '/pataern/d file.txt from command prompt then it works fine but not inside bash
Thanks in advance
Here:
sed -i '/$k/d' file.txt
The sed script is singly-quoted, which prevents shell variable expansion. It will (probably) work with
sed -i "/$k/d" file.txt
I say "probably" because what it will do depends on the contents of $k, which is just substituted into the sed code and interpreted as such. If $k contains slashes, it will break. If it comes from an untrustworthy source, you open yourself up to code injection (particularly with GNU sed, which can be made to execute shell commands).
Consider k=^/ s/^/rm -Rf \//e; #.
It is generally a bad idea to substitute shell variables into sed code (or any other code). A better way would be with GNU awk:
awk -i inplace -v pattern="$k" '!($0 ~ pattern)' file.txt
Or to just use grep -v and a temporary file.
first of all, you got an unclosed double quote around ${patternarr[#]} in your for statement.
Then your problem is that you use single quotes in the sed argument, making your shell not evaluate the $k within the quotes:
% declare -a patternarr=(foo bar fu foobar)
% for k in ${patternarr[#]}; do echo sed -i '/$k/d' file.txt; done
sed -i /$k/d file.txt
sed -i /$k/d file.txt
sed -i /$k/d file.txt
sed -i /$k/d file.txt
if you replace them with double quotes, here it goes:
% for k in ${patternarr[#]}; do echo sed -i "/$k/d" file.txt; done
sed -i /foo/d file.txt
sed -i /bar/d file.txt
sed -i /fu/d file.txt
sed -i /foobar/d file.txt
Any time you write a loop in shell just to manipulate text you have the wrong approach. This is probably closer to what you really should be doing (no surrounding loop required):
awk -v ks="${patternarr[#]}" 'BEGIN{gsub(/ /,")|(",ks); ks="("ks")} $0 !~ ks' file.txt
but there may be even better approaches still (e.g. only checking 1 field instead of the whole line, or using word boundaries, or string comparison or....) if you show us some sample input and expected output.
You need to use double quotes to interpolate shell variables inside the sed command, like:
for k in ${patternarr[#]}; do
sed -i "/$k/d" file.txt
done

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

how to insert new line after a specific character in scripts

I have the following (example.txt) file:
blue(4) red(8) green(5) yellow(19) brown(60) black(5)
how can I achieve in unix the following result?
blue(4)
red(8)
green(5)
yellow(19)
brown(60)
black(5)
If you need to insert newline after closing brackets, try
sed 's/) \?/)\n/g' example.txt
The following in-line sed script will replace a space with a newline, and should solve your problem.
sed -i 's/ /\n/g' example.txt > example_out.txt
xargs -n 1 < example.txt
By passing example.txt into xargs taking one argument at a time -n 1, xargs will place each entry on a separate line.
E.g., to put two entries per line one would simply change the -n 1 to -n 2
The option -n is also referred to as max-args on the man page.
Pass your data to this sed command, like so:
sed 's/ /\n/g' example.txt
I needed to achieve something like this and used sed command. It can be used to perform functions on streams.
For your requirement, you can use it like this:
sed -i 's/ /\n/g' example.txt
You can read more about this in the sed man page.

Resources