Use o awk para inserir uma linha após a saída N

7

Eu tenho um arquivo de texto preenchido com um monte de dados. Eu preciso retirar linhas que contêm strings específicas. Eu consegui isso com o awk usando o seguinte:

awk '/pattern1|pattern2|pattern3/ {print;}' infile

Eu então preciso colocar uma nova linha (\ n) após a terceira linha. Então, seria necessário se parecer com isso

pattern1
pattern2
pattern3
<new line>
pattern1...

Consegui fazer isso colocando o primeiro comando em outra instrução awk

awk -F '\n' '/pattern1|pattern2|pattern3/ { print; }' infile | awk '{ if ((NR % 3) == 1) printf("\n"); print; }'

Eu acho que deve haver uma maneira mais eficiente de fazer isso, então comecei a procurar para ver como eu poderia combinar os dois comandos juntos. Eu tentei o seguinte:

awk '/pattern1|pattern2|pattern3/ { if ((NR % 3) ==1 ) printf("\n"); print; }'

Eu percebi que isso funcionaria, mas a saída é completamente imprevisível, às vezes há 5 linhas agrupadas, grupos de 2 linhas, mas nenhuma linha de 3.

Eu estava pensando que talvez houvesse um problema no delimitador, então tentei brincar com a opção -F e configurar o IFS, mas não alterei a saída.

Eu acho que estou fazendo algo estúpido na maneira como tentei combinar a correspondência de padrões com a instrução if, mas não consegui descobrir a combinação.

É o que estou tentando fazer possível em um único comando awk? E se sim, para onde estou indo errado?

    
por bourne 28.05.2014 / 16:32

2 respostas

6

O problema com sua tentativa de solução é que NR do awk é uma contagem dos registros entrada , enquanto você deseja inserir a nova linha baseada na contagem do número output registros.

Eu não acho que o awk mantenha tal contagem nativamente, mas você poderia fazer algo como

awk '/pattern1|pattern2|pattern3/ {print; if (++onr%3 == 0) print ""; }' infile

em que definimos uma nova variável onr (para número de registro de saída - o nome da variável é arbitrário) e o incrementamos toda vez que combinamos / imprimimos o texto desejado, então verifique se < em> que é divisível por 3 e, se assim for, imprimir uma nova linha.

    
por 28.05.2014 / 16:58
0

eu entendi corretamente, você está tentando inventar

awk '/pattern1|pattern2/ {print $1;} /pattern3/ {print $1 "\n"}' infile
    
por 28.05.2014 / 16:56

Tags