如何仅对包含给定字符串的行进行sed处理?


13

输入:

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”“ sed”为“ XXXX”。

但是:仅在包含“选择ASDF”字符串的行中。我该怎么做?(sed,awk等:\)

Answers:


19

您可以为大多数sed命令加上地址前缀,以限制它们所应用的行。地址可以是行号或以分隔的正则表达式/

cat INPUT | sed '/Select ASDF/ s=sdfg=XXXX='

如Peter.O所述,上面编写的命令将替换sdfg包含的字符串中any的第一个匹配项Select ASDF。如果sdfg仅在第四列中需要将完全匹配替换为,则应采用以下方式:

cat INPUT | sed 's/\(^Select ASDF [^ ]* \)sdfg /\1XXXX /'

1
另一个包含sdfg的字段呢?例如。5sdfga
Peter.O 2012年

嗯,实际上这也不是问题。我已经更新了答案。
2012年

有使用的任何选项:sed'/ Select ASDF / gs = sdfg = XXXX ='-因此,我需要替换一行中所有出现的内容,而不仅仅是第一个。但如果我使用“ g”,sed会给出错误
LanceBaynes

1
您需要g最后输入=(在s命令末尾)。它将是这样的:sed '/Select ASDF/ s=sdfg=XXXX=g'
着急

7

如果仅更改第4列的值,则使用相等运算符代替正则表达式是有意义的。

awk '$1 == "Select" && $2 == "ASDF" && $4 == "sdfg" {$4 = "XXXX"} {print}'

1
快速!..比较一下,对于一百万行,使用Birei的awk和Rush的位置 sed: 0m1.580s0m3.792s0m6.740s
Peter.O 2012年

1

使用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

1
您应该提到的IGNORECASE是一个GNU awk/ gawk扩展。
2012年

1
@ jw013:谢谢。根据您的建议更新了答案。
Birei 2012年

4
IGNORECASE是错误在这种情况下,无论是GNU或G'not。在这个问题的标准是明确的大写ASDF
Peter.O
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.