Como imprimir a linha n depois da partida / linhas vazias

1

Estou tentando escrever um script curto que encontre linhas vazias e depois imprima a enésima linha depois das linhas vazias.

Para

foo1
foo2
foo3

bar1
bar2
bar3

spam1
spam2
spam3

eggs1
eggs2
eggs3

imprimir cada segunda linha depois de uma linha em branco resultaria em:

foo2
bar2
spam2
eggs2

Eu tentei usar o sed sed -n -e "/^$/ {N; N; x; N; p; x; d}" , mas não consegui limpar o espaço de espera e o resultado não é o que eu quero.

    
por Alexandru 25.03.2016 / 23:16

5 respostas

7

awk '++n == 2; !NF {n = 0}' < your-file

Ou:

sed -n '
  n;p
  :1
  /./{
    n;b1
  }' < your-file
    
por 26.03.2016 / 21:07
1

Você está contando a linha zero como uma linha em branco, o que torna um pouco mais difícil. Se ignorarmos isso e aceitarmos sua declaração literal, "imprima cada segunda linha depois de uma linha em branco", você pode fazer isso com ex :

ex -sc 'g/^$/+2p' -cq filename
  • -s : modo silencioso ( ex é, na verdade, para edição interativa).
  • -c : declara um comando para ser executado
  • g/^$/ : execute o seguinte comando g lobally em todas as linhas vazias
  • +2p : imprime a linha duas linhas abaixo da linha atual
  • q : o comando para sair

Para contar a linha 0 como uma linha em branco (mas somente se a linha 1 não for uma linha em branco), você precisa obter mais fantasia; você poderia fazer isso em ex inserindo uma linha em branco antes da linha 1, depois filtrando as linhas de 1 a 2 até uniq , mas nesse ponto provavelmente é melhor usar awk , para seus propósitos.

    
por 25.03.2016 / 23:37
1

Facilmente feito com perl :

$ perl -n -e 'BEGIN {$count=0}; 
              if (/^\s*$/) {$count=0} else {$count++};
              if ($count eq 2) {print}' alexandru.txt 
foo2
bar2
spam2
eggs2
    
por 26.03.2016 / 02:42
0

Você pode usar o awk para lembrar a última linha que estava vazia:

awk -v gap=2 'BEGIN { lastline=0 } /^$/ { lastline=NR } NR==lastline+gap { print }' test.txt

Isso significa:

  • No começo, defina a variável que indica qual foi a última linha ( lastline ) para zero. Isso corresponde ao seu requisito implícito de que a segunda linha seria impressa como se viesse depois de uma linha vazia.
  • Quando estiver em uma linha vazia, defina lastline para a linha atual.
  • Quando o número da linha atual for gap linhas após as últimas linhas vazias, imprima-o.

Você pode definir gap no começo para qualquer número. Observe que, se houver menos de gap linhas entre duas linhas vazias, a primeira linha vazia não terá efeito.

    
por 26.03.2016 / 20:29
0

Existe um valor codificado no código 2 para imprimir cada segunda linha após a linha vazia.

Experimente:

awk 'BEGIN { empty=1; n=0; } { if ($0 ~ /^$/) { empty=1; n=0; } else if (empty) { n++; if (n==2) { empty=0; print; } } }' file.txt

file.txt é o nome do arquivo a ser analisado no diretório atual.

Assume-se que sempre há n linhas ou mais depois de cada linha vazia, quando pesquisando a nª, certo?

A saída do teste está abaixo:

awk 'BEGIN { empty=1; n=0; } { if ($0 ~ /^$/) { empty=1; n=0; } else if (empty) { n++; if (n==2) { empty=0; print; } } }' file.txt
foo2
bar2
spam2
eggs2

----

Há uma página famosa: Sed - Uma Introdução e Tutorial de Bruce Barnett

Experimente esta versão abaixo, que é muito próxima da sua:

sed -n '{
2 {
p
}
/^$/ {n
n
p}}' file.txt

foo2
bar2
spam2
eggs2
    
por 25.03.2016 / 23:47