Selecione a linha com a linha vazia acima e abaixo

1

Eu tenho o seguinte "problema". Eu tenho uma saída que se parece com isso:

A
A
A

B

A
A
A

C

A
...

Eu gostaria de filtrar as linhas cercadas por linhas vazias.
Neste exemplo, seria B e C e assim por diante.

    
por raddirad 18.04.2017 / 18:11

4 respostas

3

awk lê a entrada como "parágrafos", ou registros separados por linhas vazias se RS estiver definido para a cadeia vazia ( GNU awk ). (configurar RS para \n\n+ é semelhante, mas não exatamente.) Você pode imprimir todos os registros que não contêm uma nova linha:

$ awk -vRS= '$0 !~ /\n/' file1
B
C

Isso também imprimia a primeira e a última linha, se forem seguidas ou precedidas por uma linha vazia, tratando o início e o fim do arquivo como "linhas vazias". Se você quiser linhas vazias reais, algo assim faria:

awk 'BEGIN {lines=2} /^$/ {if (lines == 1) print prev; lines=0 } 
     !/^$/ {lines += 1}  {prev=$0}' file1
    
por 18.04.2017 / 18:18
1

Tente:

awk -v RS= '!/\n/'

Isso informa os parágrafos que têm apenas uma linha.

Tecnicamente, se o arquivo continha:

A

B
C

D

E

Isso também relataria A e E , mesmo que não sejam precedidos (respectivamente seguidos) por uma linha vazia.

Se você quisesse apenas D acima, poderia fazer:

awk '
  {
    if ($0 != "") {
      ok = wasempty
      wasempty = 0
    } else {
      if (ok) print last
      ok = 0
      wasempty = 1
    }
  }
  ok {last = $0}'
    
por 18.04.2017 / 18:19
1

Se a primeira / última linha for descartada porque não pode ter linhas vazias nos dois lados:

$ cat ip.txt 
A0

B1

A2

A
A

C3

AN
$ awk 'NR>=3 && p2~/^$/ && p1~/./ && /^$/{print p1} {p2=p1; p1=$0}' ip.txt 
B1
A2
C3
  • NR>=3 precisa de pelo menos três linhas para corresponder à condição
  • {p2=p1; p1=$0} salvando a última linha em p1 e a última a última linha em p2
  • p2~/^$/ && p1~/./ && /^$/ correspondente à condição dada, supõe que a correspondência de linha vazia não deve ter espaços em branco e que a linha a corresponder NÃO está vazia
por 18.04.2017 / 18:35
0
perl -l -0777ne 'print for /(?:^|\n)\n\K.+(?=\n\n)/g' yourfile

Explicação:

We slurp the file and then the whole file is a single record. In that single record we zoom in on islands which are preceded by 2 consecutive line beginnings and followed by 2 newlines. All such islands are printed by the for loop.

sed -e '
   /./d      # skip a nonempty line
   $!N       # grab the line following an empty line
   /^\n$/D   # if we have 2 consecutive empties, clip the former, n branch to top
   $!N       # we now have ^\nLine\n...
   /\n$/!D   # clip if the seq ^\nLine\n$ not found
   s/.//     # found it! ^\nLine\n$
   P;D       # 
' yourfile
    
por 18.04.2017 / 22:35