仅在文件中的 grep 行上使用 sed

仅在文件中的 grep 行上使用 sed

我有一个文件,其中包含如下内容:

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=truestandalone=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=muzillafullname=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。

相关内容