我知道 sed 可以像这样替换文本文件中的一段字符串:
sed -i 's/oldstring/newstring/g' test.txt
但是,如果该行存在,我该如何替换它?如果该行不存在,我该如何自动将其添加到新行?
谢谢。
编辑:感谢您的回复。根据您对评论和回答的要求,以下是更多详细信息:
- 我想检查旧字符串是否存在,如果存在就用新字符串替换它。
- 如果旧字符串不存在,我想在 txt 文件末尾的新行中添加新字符串
- 如果同一个字符串出现多次,那么就会出现错误,因为它是一个配置文件。在替换第一次出现之后,可以删除其他出现的内容。
答案1
一种方法是将其带入grep
方程式。首先快速检查文件是否包含字符串grep
,然后相应地附加或替换:
grep -q string file &&
sed -i 's/string/newstring/' file || echo "newstring" >> file
以上是简写方式:
if grep -q string file; then
sed -i 's/string/newstring/' file
else
echo "newstring" >> file
fi
不过,就我个人而言,我会使用perl
它。只需读取文件一次,如果进行了替换,则将变量设置为 1。然后,最后,如果变量不是 1,则添加字符串:
perl -lpe '$i=1 if s/oldstring/newstring/;
END{print "newstring" if $i!=1;}' file > tmpfile && mv tmpfile file
答案2
这应该可以实现所需的目的:
grep -q "oldstring" test.txt
if [ $? -eq 1 ]; then
echo "newstring" >> test.txt
else
sed -i 's/oldstring/newstring/g' test.txt
fi
答案3
使用 AWK:
<<<"$(<in)" awk '{if(/foo/){x=sub(/foo/, "bar", $0)};print}END{if(x!=1){print "bar"}}' >in
% cat in1
string oldstring string
% cat in2
string foo string
% <<<"$(<in1)" awk '{if(/oldstring/){x=sub(/oldstring/, "newstring", $0)};print}END{if(x!=1){print "newstring"}}' >in1
user@user-X550CL ~/tmp % cat in1
string newstring string
% <<<"$(<in2)" awk '{if(/oldstring/){x=sub(/oldstring/, "newstring", $0)};print}END{if(x!=1){print "newstring"}}' >in2
% cat in2
string foo string
newstring
答案4
这是正确答案,因为上述提议对于多次调用脚本来说是非法的。例如,您有文件 text1:
echo "1aaab" > text1
和脚本:
grep -q 1aaab text1&&
sed -i 's/1aaab/aaab/' text1|| echo "aaab" >> text1
第一次通话你会得到:
aaab
其次:
aaab
aaab
正确的脚本如下:
_conf=/etc/sysctl.conf # our file
_commented=#net.ipv4.ip_forward=1 # searched insufficient text
_uncommented=net.ipv4.ip_forward=1 # text to reaplace insufficient or absent text
grep -q $_commented $_conf && (sed -i 's/'$_commented'/'$_uncommented/ $_conf || echo $_uncommented >> $_conf)
- 如果网.ipv4.ip_forward=1缺席 - 将添加新记录网.ipv4.ip_forward=1
- 如果存在(用#注释)- 将取消注释#net.ipv4.ip_forward=1到网.ipv4.ip_forward=1
- 和将不会产生每次脚本调用时都有多个预期文本副本(net.ipv4.ip_forward=1)