Imprima certos campos de cada linha até que um marcador seja encontrado, depois imprima linhas inteiras até o final do arquivo

0

Oi tenha o seguinte arquivo

 more  file.txt

 1 2 3 4 4 2
 23 4 5 23 2 3
 END_OF_LINE
 1 3 7 4 2 
 23 4 6 7 4 2 1 5 

Como imprimir apenas os campos 4 e 5 e 6 de cada linha até que a linha END_OF_LINE seja encontrada e, a partir desse ponto até o final do arquivo, imprimir toda a linha?

Eu tenho apenas uma solução parcial

 awk '{print $4" "$5" "$6}'  

Exemplo: a saída desejada para a entrada dada é:

 awk syntax ..... file.txt 
 4 4 2
 23 2 3
 END_OF_LINE
 1 3 7 4 2 
 23 4 6 7 4 2 1 5 
    
por Eytan 26.12.2013 / 19:29

3 respostas

2

Veja o que eu criei:

awk '
    /END_OF_LINE/{ matched = 1}  # When you find END_OF_LINE set the matched flag
    {
        if( matched == 0)        # If you haven't matched END_OF_LINE yet
             print $4" "$5" "$6  # ...print the required fields
        else                     # If you have already found END_OF_OLINE
             print $0            # ...print the whole line
    }' your_file

mas eu não sou um cara awk : tenho certeza que isso pode ser melhor simplificado.

    
por 26.12.2013 / 19:49
0

Isso é mais fácil feito no sed.

sed -n '1,/END_OF_LINE/ {s/^\([^ ]* \)\{3\}\(.*\)$//p};/END_OF_LINE/,$p' file.txt
    
por 26.12.2013 / 20:07
0

Aqui está um casal. O awk é apenas a solução de Joseph, mas escrito de uma maneira mais concisa. Tudo isso depende da mesma ideia básica. Basta definir uma variável como 1 quando a linha correspondente for encontrada e verificar o valor dessa variável para decidir o que imprimir.

  1. awk

    awk '/END_OF_LINE/{ m = 1}(m==0){print $4,$5,$6; next}1;' file.txt 
    
  2. Perl

    perl -alne '$m++ if /END_OF_LINE/; $m==0? print "@F[3..5]" : print; ' file.txt 
    

    A mágica está nas opções de perl :

    -a     turns on autosplit mode when used with a -n or -p. An implicit split command to the @F array is done as the first thing inside the implicit while loop produced by the -n or -p.

    Isso faz com que ele aja essencialmente como awk . O -n significa apenas processar um arquivo de entrada linha a linha e o -l significa adicionar uma nova linha a cada declaração impressa (isso significa muito mais, mas é o que está fazendo aqui). Finalmente, o -e é apenas uma maneira de passar um script na linha de comando.

por 27.12.2013 / 14:50