Anexar linhas que não contenham “|” à linha anterior

1

Eu tenho um arquivo de texto que contém dados no formato abaixo.

1|0|this is test file line1
2|1|this is test file line2
3|1|this
is
test
file line4

Qualquer linha que não contenha | deve ser anexada à linha anterior que contém |

Saída:

1|0|this is test file line1
2|1|this is test file line2
3|1|this is test file line4
    
por Harish 17.12.2017 / 16:57

6 respostas

4

Uma maneira é usar o Awk para implementar o seguinte algoritmo:

  • Acompanhe a linha anterior em prev
  • Se a linha contiver | e não for a primeira linha, imprima prev . Depois disso, armazene a linha atual em prev
  • Se a linha não contiver | , anexe-a a prev
  • No final do script, imprima prev

Por exemplo, assim:

awk '/\|/ { if (NR > 1) print prev; prev=$0 }
     !/\|/ { prev = prev $0 }
     END { print prev }' input
    
por 17.12.2017 / 17:09
2

Use | como o separador de campo: se a linha contiver | , a variável NF será maior que um.

awk -F'|' 'NR > 1 && NF > 1 {print ""} {printf "%s", $0} END {print ""}' file
    
por 17.12.2017 / 17:15
2
awk '/\|/ { if (printed==1) print ""; else printed=1;
    printf "%s",$0; next; }; { printf " %s",$0 }; END { print ""; }' inputfile

Ou, se você não se importa com a nova linha principal, menor:

awk '/\|/ { printf "\n%s",$0; next; }; { printf " %s",$0 }; END { print ""; }' inputfile
    
por 17.12.2017 / 17:15
1

Awk é meu utilitário go-to para manipulação de texto:

awk '/\|/ && NR>1 { printf "\n" } !/\|/ && NR>1 { printf " " } { printf $0 } END { printf "\n" }' file
  1. Imprima um caractere de nova linha se a linha contiver | (mas não para a primeira linha):
    /\|/ && NR>1 { printf "\n" }
  2. Caso contrário, imprima um espaço (mas não para a primeira linha):
    !/\|/ && NR>1 { printf " " }
  3. Imprima a linha inteira, sem um caractere de nova linha:% { printf $0 }
  4. Imprima uma nova linha no final do arquivo:
    END { printf "\n" }
por 17.12.2017 / 23:58
0

Mais um awk:

awk -F'|' 'NR>1{printf prev (NF>1?"\n":" ")}{prev=$0}END{print prev}' file

Teste

$ cat file1
1|1|this is test file line1
2|2|this is test file line2
3|3|this
is
test
file line3
4|4|this is test file line4
5|5|this is
test file
line5
6|6|this is test file line6

$ awk -F'|' 'NR>1{printf prev (NF>1?"\n":" ")}{prev=$0}END{print prev}' file1
1|1|this is test file line1
2|2|this is test file line2
3|3|this is test file line3
4|4|this is test file line4
5|5|this is test file line5
6|6|this is test file line6 
    
por 17.12.2017 / 20:56
0

Eu faria isso usando o Perl:

perl -e '$f=1;while(<>){chomp;print(($f?"":/\|/?"\n":" ").$_);$f=0}'

Como alternativa, você pode usar este script sed:

sed -E ':s;N;s/\n([^\n|]*)$/ /;bs'

É um loop que

  • N lê uma linha e a anexa ao espaço padrão
  • s/\n([^\n|]*)$/ / se a linha no espaço de padrão não contiver | , substitua a nova linha por um espaço
  • bs pula de volta para o :s label
por 18.12.2017 / 00:14