我有一个如下文本文件
name: xyz
ip: x.x.x.x
network: abc
gateway: def
name: xyz
ip: x.x.x.x
network: abc
gateway: def
以上2个代码块,我想编写一个多行的sed命令,可以替换' name'和'网络'信息,然后将其重定向到同一个文件
我在下面试过
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
以上命令仅替换'网络'部分来自文本文件,但没有取代'名称'一部分。
sed / bash expert plesae阐明了如何使用sed命令替换多个内容并将输出重定向到temp.txt文件?
谢谢
答案 0 :(得分:2)
您的while read
循环在此无效。您的sed命令实际上已经执行了您想要的操作:
$ 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
请注意,我已将sed one-liner括在单引号中,并从每个替换中删除g
修饰符,这是不必要的,因为您只打算每行执行一次替换。
目前还不清楚您是否要覆盖原始文件 - 您似乎正在尝试同时执行这两项操作。如果您想覆盖您的输入文件(并且您的sed版本支持它),您可以使用-i
开关:
sed -i 's/xyz/abc/; s/network:.*/network: temp_net/' file
这将覆盖file
。某些版本的sed要求您为备份文件指定后缀:
sed -i.bak 's/xyz/abc/; s/network:.*/network: temp_net/' file
在这种情况下,file
仍会被覆盖,但原件的备份会在file.bak
中进行。
如果您只想将结果输出到新文件,只需要一个简单的重定向:
sed 's/xyz/abc/; s/network:.*/network: temp_net/' file > new_file
答案 1 :(得分:1)
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.*.
答案 2 :(得分:0)
如果您只是尝试交换文本,我可能会链接seds,然后将输出存储在一个临时文件中,然后将其重新保存到原始文件中 - 可能不是最佳解决方案,但它的首先想到的是。
我在script.sh中有这个。
SKIP LOCKED
然后你可以简单地运行:
#!/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
希望有所帮助。