Reputation: 199
I have a text file like below
name: xyz
ip: x.x.x.x
network: abc
gateway: def
name: xyz
ip: x.x.x.x
network: abc
gateway: def
The above 2 blocks of code, I want to write a multi-line sed command which can replace 'name' and 'network' information and then redirect it to the same file
I tried below
while read line; do
cat $line 2> /dev/null | sed -i s/xyz/abc/g;s/network:.*/network: temp_net/g test.txt > ~/temp-file.txt
done
The above command only replaces the 'network' part from the text file but doesnt replace the 'name' part.
sed/bash experts plesae shed some light on how should I use sed command to replaces multiple things and redirect output to a temp.txt file ?
Thank you
Upvotes: 1
Views: 3180
Reputation: 203684
sed
is the wrong tool for any task involving multi-line blocks of input because it's line-oriented. You should be using awk as it's record-oriented and so can treat each multi-line block of input a easily as sed can handle lines of input.
$ awk -v RS= -v ORS='\n\n' '{sub(/xyz/,"abc"); sub(/network:[^\n]+/,"network: temp_net")}1' file
name: abc
ip: x.x.x.x
network: temp_net
gateway: def
name: abc
ip: x.x.x.x
network: temp_net
gateway: def
Run it as awk '...' file > tmp && mv tmp file
to change the original file, or you can use awk -i inplace '...' file
if you have GNU awk 4.*.
Upvotes: 1
Reputation: 724
If you're just trying to swap text I'd probably chain seds and then store the output in a temporary file and then cat it back into the original file - probably not the best solution, but its the first that comes to mind.
I have this in a script.sh
#!/bin/bash
while read line
do
echo $line | sed s/xyz/temp1/g | sed s/abc/temp2/g | sed s/temp1/abc/g | sed s/temp2/xyz/g
done < $1 > $2
cat $2 > $1
Then you can simply run:
chmod +x script.sh
./script.sh input.txt output.txt
Hope that helps.
Upvotes: 0
Reputation: 74655
Your while read
loop serves no purpose here. Your sed command actually does what you want already:
$ cat file
name: xyz
ip: x.x.x.x
network: abc
gateway: def
name: xyz
ip: x.x.x.x
network: abc
gateway: def
$ sed 's/xyz/abc/; s/network:.*/network: temp_net/' file
name: abc
ip: x.x.x.x
network: temp_net
gateway: def
name: abc
ip: x.x.x.x
network: temp_net
gateway: def
Note that I've enclosed your sed one-liner in single quotes and removed the g
modifiers from each of the substitutions, which are unnecessary as you only intend on performing one substitution per line.
It is unclear whether you're looking to overwrite the original file or not - you seem to be attempting to do both at the moment. If you want to overwrite your input file (and your version of sed supports it), you can use the -i
switch:
sed -i 's/xyz/abc/; s/network:.*/network: temp_net/' file
This will overwrite file
. Some version of sed require that you specify a suffix for a backup file:
sed -i.bak 's/xyz/abc/; s/network:.*/network: temp_net/' file
In this case, file
is still overwritten but a backup of the original is made in file.bak
.
If you just want to output the result to a new file, a simple redirection is all you need:
sed 's/xyz/abc/; s/network:.*/network: temp_net/' file > new_file
Upvotes: 2