awk altera a próxima linha após uma correspondência de padrão baseada em outra correspondência de padrão

2

Eu tenho um arquivo com linhas como:

....
pattern1 100 200 300
pattern2 300 400 400
pattern1 300 900 700
pattern1 200 500 900
...

Como mostrado no exemplo acima, há algumas linhas em que pattern2 segue pattern1 , mas não todos. Eu gostaria de corresponder pattern1 , em seguida, verifique se a próxima linha tem pattern2 e se isso acontecer, altere o campo do número seguinte, multiplicando-o com um fator constante. Eu tentei usar getline com awk , mas apaga as linhas com pattern1 da saída resultante:

awk '/pattern1/{getline; if($1==pattern2) $(NF-2)*=0.889848406214}1' infile.dat

Alguma sugestão de como posso fazer isso sem alterar mais nada no arquivo de entrada.

    
por Ketan 28.01.2016 / 17:53

2 respostas

3
awk '
  /pattern1/ { f = 1; print; next }
  f && /pattern2/ { $(NF-2) *= 0.889848406214 }
  { f = 0; print }
' <file
    
por 28.01.2016 / 18:04
2

Sua abordagem está falhando porque getline se move imediatamente para a próxima linha para que a linha atual seja perdida. Uma solução simples seria salvar a linha atual em uma variável e então passar para a próxima:

$ awk '{
        if(/pattern1/){
            l=$0; 
            getline; 
            if($1=="pattern2"){
                $(NF-2)*=0.889848406214
            } 
            print l"\n"$0
        }
        else{print}
       }' file
pattern1 100 200 300
pattern2 266.955 400 400
pattern1 300 900 700
pattern1 200 500 900

Como alternativa, use um sinalizador que controle se a linha anterior correspondeu a pattern1 :

$ awk '{if(/pattern2/ && l){$(NF-2)*=0.889848406214} /pattern1/ ? l=1 : l=0;}1;' file
pattern1 100 200 300
pattern2 266.955 400 400
pattern1 300 900 700
pattern1 200 500 900
    
por 28.01.2016 / 18:09