查找包含 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
这里的不同之处在于我们要求再次将搜索定位到行的开头 (^
),然后是零个或多个 (*
) 个字符不是 #
([^#]
)。
我想在文件中注释包含 '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 -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
这里的不同之处在于我们要求再次将搜索定位到行的开头 (^
),然后是零个或多个 (*
) 个字符不是 #
([^#]
)。