如何仅 sed 包含给定字符串的行?

如何仅 sed 包含给定字符串的行?

输入:

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

相关内容