查找包含 UNIX 路径的行并从文件中对其进行注释

Find a line containing a UNIX path and comment it from a file

我想在文件中注释包含 'start /usr/lib/sendmail "$src_running"' 的行

$ grep /usr/lib/sendmail /tmp/tcpip
# "/usr/lib/sendmail -bi" or "/usr/ucb/newaliases".
start /usr/lib/sendmail "$src_running" "-bd -q${qpi}"


$ grep /usr/lib/sendmail /tmp/tcpip
# "/usr/lib/sendmail -bi" or "/usr/ucb/newaliases".
#start /usr/lib/sendmail "$src_running" "-bd -q${qpi}"

sed 无法搜索字符串,只能搜索正则表达式(参见 ),因此您最好使用像 awk 这样的工具,当您想要匹配字符串时,它可以理解字符串:

$ awk -v str='start /usr/lib/sendmail "$src_running"' 'index([=10=],str){[=10=]="#"[=10=]} 1' file
# "/usr/lib/sendmail -bi" or "/usr/ucb/newaliases".
#start /usr/lib/sendmail "$src_running" "-bd -q${qpi}"

sed 命令也适用于此。 这是一个示例解决方案:

sed -r 's|start /usr/lib/sendmail "$src_running"|#&|' inputfile

一个解释:

-r 选项提供扩展的正则表达式,避免大量引用。但是 Linux 特定且跨其他 sed 版本的可移植性较差。

s 用于替换的 sed 命令。

| 搜索模式标记和替换模式标记

$ 引用 $,转义 $ 正则表达式行尾锚点

#&替换模式,#为注释前缀,&为匹配搜索模式

希望这对你有用。

由于普通 AIX sed 和 awk 不提供就地编辑,您可以考虑 sed 的前身,ed! 如果您喜欢,它可以编写脚本并就地编辑文件的东西:

ed -s /tmp/tcpip << 'EOF'
/start \/usr\/lib\/sendmail "$src_running"/s/^/# /
w
q
EOF

这会使用 -s 选项在 /tmp/tcpip 上调用 ed,这会抑制读取和写入的字节数的正常报告。然后它发送 ed 包含命令列表的 quoted here-document。我在此处引用了一个文档,以防止对变量进行任何无意的解释,例如 $src_running.

这里唯一有趣的 ed 命令是第一个;它的目的是找到我们之后的行,然后将其注释掉。最后两行只是 w 将文件写回磁盘并 q 编辑。主要命令分为两部分:

  • 地址,由搜索范围/start \/usr\/lib\/sendmail "$src_running"/指定,
  • 动作,即搜索和替换s/^/# /

搜索范围看起来有点滑稽,因为正斜杠是定界符,所以我们需要转义作为搜索文本一部分的正斜杠。搜索和替换只是说用散列标记和 space.

替换行的开头(特殊标记 ^

请注意,这直接回答了您有关查找该文本的 (第一个)匹配项的问题;它不会替换 all 匹配行。如上所述,它也不关心该行当前是否被注释掉。注释掉该行两次并没有什么坏处,但是如果你想更严格地搜索,你可以使用:

ed -s /tmp/tcpip << 'EOF'
/^[^#]*start \/usr\/lib\/sendmail "$src_running"/s/^/# /
w
q
EOF

这里的不同之处在于我们要求再次将搜索定位到行的开头 (^),然后是零个或多个 (*) 个字符不是 #[^#])。