Como sed apenas as linhas que contém uma string dada?

12

ENTRADA:

Select ASDF 325 sdfg sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg sdfg 4456 sdrg

OUTPUT:

Select ASDF 325 XXXX sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg XXXX 4456 sdrg

Então, resumidamente, preciso "sed" "sdfg" para "XXXX".

MAS: apenas nas linhas que contém a string "Select ASDF" .. Como posso fazer isso? (sed, awk, etc.: \)

    
por LanceBaynes 28.04.2012 / 08:59

3 respostas

18

Você pode prefixar a maioria dos comandos sed com um endereço para limitar as linhas às quais se aplicam. Um endereço pode ser um número de linha ou uma regex delimitada por / .

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

Como mencionado Peter.O, o comando conforme descrito acima substituirá a primeira ocorrência de qualquer sdfg na string contendo Select ASDF . Se você precisar substituir a correspondência exata para sdfg apenas no caso em que está na quarta coluna, você deve seguir este caminho:

cat INPUT | sed 's/\(^Select ASDF [^ ]* \)sdfg /XXXX /'
    
por 28.04.2012 / 09:08
7

Se você só estiver alterando a coluna 4 se ela tiver o valor exato, usar os operadores de igualdade em vez de expressões regulares faz sentido.

awk '$1 == "Select" && $2 == "ASDF" && $4 == "sdfg" {$4 = "XXXX"} {print}'
    
por 28.04.2012 / 13:38
1

Usando GNU awk :

awk '
    BEGIN { IGNORECASE = 1 } 
    /^select asdf/ { 
        sub( /\<sdfg\>/, "XXXX", $0 ) 
    } 
    { print }
' infile

Saída:

Select ASDF 325 XXXX sdflk lk
Select TRG 46sdg rasdftz fsgs 45
Select ASDF 6ffg XXXX 4456 sdrg

UPDATE : evite IGNORECASE para um não-GNU awk e combine maiúsculas e minúsculas. Graças a jw013 , que apontou esse detalhe:

awk ' 
    /^Select ASDF/ { 
        sub( /\<sdfg\>/, "XXXX", $0 ) 
    } 
    { print }
' infile
    
por 28.04.2012 / 09:59

Tags