![如何仅 sed 包含给定字符串的行?](https://linux22.com/image/22679/%E5%A6%82%E4%BD%95%E4%BB%85%20sed%20%E5%8C%85%E5%90%AB%E7%BB%99%E5%AE%9A%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E8%A1%8C%EF%BC%9F.png)
输入:
Select ASDF 325 sdfg sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg sdfg 4456 sdrg
输出:
Select ASDF 325 XXXX sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg XXXX 4456 sdrg
简而言之,我需要将“sed”“sdfg”转换为“XXXX”。
但是:仅在包含“Select ASDF”字符串的行中。我该怎么做? (sed、awk 等:\)
答案1
您可以在大多数 sed 命令前面加上前缀地址限制它们适用的行。地址可以是行号,也可以是由 分隔的正则表达式/
。
cat INPUT | sed '/Select ASDF/ s=sdfg=XXXX='
正如 Peter.O 提到的,上面写的命令将替换sdfg
包含 的字符串中第一次出现的 any Select ASDF
。如果您需要将精确匹配替换为sdfg
仅在第四列中的情况下,您应该这样做:
cat INPUT | sed 's/\(^Select ASDF [^ ]* \)sdfg /\1XXXX /'
答案2
如果您仅更改第 4 列(如果它具有精确值),那么使用相等运算符而不是正则表达式是有意义的。
awk '$1 == "Select" && $2 == "ASDF" && $4 == "sdfg" {$4 = "XXXX"} {print}'
答案3
使用GNU awk
:
awk '
BEGIN { IGNORECASE = 1 }
/^select asdf/ {
sub( /\<sdfg\>/, "XXXX", $0 )
}
{ print }
' infile
输出:
Select ASDF 325 XXXX sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg XXXX 4456 sdrg
更新:避免IGNORECASE
用于非 GNU awk
,并且匹配区分大小写。谢谢jw013,他指出了这个细节:
awk '
/^Select ASDF/ {
sub( /\<sdfg\>/, "XXXX", $0 )
}
{ print }
' infile