Script awk para extrair uma parte do arquivo de entrada

3

Como eu escrevo um script awk que varre o arquivo de entrada para "start" e encontra a linha contendo "next" e exibe a seguinte linha? Algo parecido com isto:

    [user]$ cat test.txt
    start
    next
    This line should print
    Ignore this


    [user]$ display.awk test.txt
    This line should print

    [user]$ cat test1.txt
    Ignore this
    next
    Ignore this
    start
    Ignore this
    next
    This line should print
    Ignore this
    next
    Too late so ignore this too
    start
    Ignore this too

    [user]$ display.awk test1.txt
    This line should print
    
por bbycakes3 28.10.2015 / 06:23

3 respostas

5

Aqui está um verso:

awk 'BEGIN {start="no"; nextline="no"}; nextline=="yes" {print; exit}; (start=="yes" && /^next$/) {nextline="yes"}; /^start$/ {start="yes"}' test.txt 

E como um script autônomo:

#!/bin/awk -f

BEGIN {start="no"; nextline="no"}
nextline=="yes" {print; exit}
(start=="yes" && /^next$/) {nextline="yes"}
/^start$/ {start="yes"}

Explicação

Isso pode fazer mais sentido lendo primeiro o primeiro ponto, depois lendo o resto ao contrário.

  • BEGIN {start="no"; nextline="no"} : para começar, defina ambas as variáveis como "no" (ou seja, ainda não as encontramos). N.B. next é uma palavra reservada, então usei nextline .
  • nextline=="yes" {print; exit} : quando tivermos encontrado next de uma linha anterior, imprima a linha e saia.
  • (start=="yes" && /^next$/) {nextline="yes"} : depois de encontrar o start , se também encontrarmos next em uma linha, defina nextline para "yes"
  • /^start$/ {start="yes"} : se encontrarmos início, defina start para "yes" .
por 28.10.2015 / 06:40
4

Solução alternativa com sed :

sed -n '/start/,${        # in this range
$!{                       # if not the last line                         
/next/{                   # and if line matches "next"
n                         # read in the next line
p                         # print pattern space
q                         # quit
}
}
}' infile

com gnu sed :

sed -n '/start/,${$!{/next/{n;p;q}}}' infile
    
por 28.10.2015 / 08:27
1

isso também deve funcionar

awk 'BEGIN {l1=0} /^start$/{l1=1} /^next$/ && l1==1 {l2=NR+1} NR==l2 {print;l1=0}' test.txt

usa o número de registro NR para imprimir o registro após o primeiro próximo encontrado depois de uma linha de partida.

    
por 28.10.2015 / 16:28