替换或添加字符串到文件

替换或添加字符串到文件

我知道 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)

相关内容