我有一个文件,其中包含如下内容:
192.168.1.1 user=a pass=b name=muzi standalone=true
192.168.1.2 user=a pass=b name=muzi standalone=true
192.168.1.3 user=a pass=b name=muzi standalone=true
我试图找到最好的方法来 grep 文件中包含 name=muzi 的行,然后运行 sed 将 standalone=false 更改为除第一个实例之外的所有这些行。所以我会
文件.txt
192.168.1.1 user=a pass=b name=muzi standalone=true
192.168.1.2 user=a pass=b name=muzi standalone=false
192.168.1.3 user=a pass=b name=muzi standalone=false
我已经找到了一种使用临时文件来实现这一点的方法,但是这个代码太糟糕了,我相信有一个简单的方法可以做到这一点
答案1
此答案假设“除第一个实例之外的所有这些行”的意思是“…除第一个实例之外name=muzi
”,而不是“…除第一个实例之外name=muzi standalone=true
”。因此,第一个name=muzi
是“第一个实例”,无论它是什么standalone
,甚至是否出现在行中。
答案还假设您想要将精确的字符串更改standalone=true
为standalone=false
。例如,standalone=auto
不会更改。
这sed
可能不是最简单的解决方案:
<datafile sed '
/\bname=muzi\b/ { # only for lines matching the pattern
x # exchange hold and pattern spaces
s/^$// # if former hold space empty
t lbl # then go to lbl
g # else get the former pattern space back
s/\bstandalone=true\b/standalone=false/ # actual replacement
h # copy pattern space to hold space
:lbl # the label
g # copy hold space to pattern space
}'
保持空间最初是空的。任何遇到name=muzi
都会使保持空间变为非空。空保持空间是name=muzi
第一次被看到的指标。
\b
是与单词边界匹配的锚点。我在我认为合适的地方使用了它。这样,name=muzilla
或fullname=muzi
就不standalone=true1
匹配。
答案2
如果您允许使用 grep 和 sed 以外的其他工具,则以下内容将替换所有出现的内容:
awk '$4=="name=muzi" { $5 = "standalone=false" }
{ print}'
为了避免更换第一个姓名=muzi行,添加测试。
awk '$4=="name=muzi" { if (do_it) $5 = "standalone=false"
else do_it=1 }
{ print }'
do_it
本程序启动时自动初始化为0。