Como ler certas linhas depois de encontrar algum texto?

8

Como posso ler um determinado número de linhas depois de encontrar algum texto?

Eg.:

Leia as próximas 2 linhas depois de encontrar "Unix" em:

Test 1
Test 2
Test 3
Test 4
UNIX
Test 5
Test 6
Test 7
Test 8
Test 9

O resultado pode ser:

Test 5
Test 6

Nota: O "Unix" no último exemplo é um argumento e, portanto, pode ser qualquer outro texto.

O que eu tenho:

Ainda estou sem ideias, preciso apenas de uma luz. Pensando em criar outro script para fazer isso.

    
por Cold 15.10.2014 / 16:35

6 respostas

8

Uma solução awk :

$ awk '$0 == "UNIX" {i=1;next};i && i++ <= 2' file
Test 5
Test 6

Explicação

  • /^UNIX$/{i=1;next} : se virmos UNIX , definimos a variável i = 1 , processando para a próxima entrada.

  • Se a variável i estiver definida (ou seja, UNIX ), i && i++ <= 2 será avaliado apenas como valor real nas próximas duas linhas depois de UNIX , fazendo com que awk execute a ação padrão print $0 .

  • Antes de ver UNIX , i não foi definido e começa na terceira linha depois de UNIX , i ter um valor maior que 2, o que torna a expressão i && i++ <= 2 avaliada como falsa, causando awk não faz nada.

por 15.10.2014 / 16:48
9

Uma solução grep :

grep -A2 -P '^UNIX$' file

Explicação: -A significa: imprima as próximas duas linhas após a correspondência

ou awk:

awk '$0=="UNIX"{getline; print; getline; print}' file

Explicação: Essa instrução procura o UNIX na linha ( $0=="UNIX" ). Se isso for fornecido, ele recebe o próximo próximo em seu buffer ( getline ) e imprime o buffer ( print ). Isso é feito duas vezes.

Ou use sed :

sed -n '/^UNIX$/{n;p;n;p}' file

Explicação: Essas pesquisas para UNIX ( /^UNIX$/ ). Se isso for encontrado, ele substitui a parte em {...} . n significa próximo, p significa impressão. Isso é feito duas vezes também.

    
por 15.10.2014 / 16:42
4
grep -A 2 UNIX file.txt

A manpage do grep descreve a opção assim:

  -A NUM, --after-context=NUM
      Print NUM  lines  of  trailing  context  after  matching  lines.
      Places  a  line  containing  --  between  contiguous  groups  of
      matches.
    
por 15.10.2014 / 16:41
0

Isso parece funcionar bem:

sed -n '/UNIX/{n;p;n;p}' /path/to/file

Prova de conceito:

$ for i in {1..9}; do echo $i; done | sed -n '/4/{n;p;n;p}'
5
6
    
por 15.10.2014 / 23:41
0

Você pode usar ex :

ex -s +'1,/UNIX/d|%p|q!' file_or_/dev/stdin

onde:

por 12.08.2015 / 11:13
-1

O que preciso fazer se precisar copiar um determinado conjunto de linhas da string correspondente para outra string correspondente.

Exemplo:

www qqq unix ddd fff ggg hhh Till here ggg ggg

Eu preciso copiar linhas do Unix até aqui. Qualquer ideia

    
por 24.08.2017 / 12:32

Tags