Merge Next Line com a linha anterior

1

Eu tenho um arquivo de texto com linhas como:

LIN This is the value which I need
      from this line which has a very long line
SHR This1;This2;
     This3;
GYC This is an extra.

E a saída deve ser como:

LIN This is the value which I need from this line whi a very..
SHR This1;This2;This3;
GYC This is an extra.

Eu estava tentando isso em sed antes de poder fazer isso em Python. Então eu consegui chegar ...

sed 's/     //' filename.txt 

O snippet acima faz apenas uma coisa, ele remove os espaços vazios de 4 + 1 (sempre corrigidos), mas agora eu não tenho certeza de como ir adiante porque tenho que mover as linhas para as tags LINE e SHRT então eu sou capaz de extrair informações. Além disso, quando a linha de tag (com linha / SHRT / EKY / EKC / USER) está continuando, ela é indicada por um único espaço extra. E se deveria ser nova linha, então continua na próxima linha.

Pergunta, pode sed ser usado para mover a linha para a linha anterior? Como posso diferenciar o espaço vazio para indicar se a linha continua ou termina

    
por Noel Alex Makumuli 01.09.2017 / 15:50

3 respostas

2

Mantenha a simplicidade:

sed 'H;1h;$!d;g;s/\n  */ /g'

Este script curto unirá todas as linhas que começam com pelo menos um espaço com a linha anterior.

Como funciona: H acrescenta cada linha ao espaço de espera. Para evitar uma nova linha principal, a primeira linha é copiada por 1h . Se essa não foi a última linha, d elete, caso contrário, mova o espaço de suspensão para o espaço de padrão com g . Agora, o arquivo inteiro está no espaço padrão e agora o comando s substitui todas as novas linhas por espaços em um espaço.

Com o GNU sed , você pode simplificar ainda mais:

sed -z 's/\n  */ /g'
    
por 01.09.2017 / 18:32
1

Outra maneira com AWK :

awk '{$1=$1;printf("%s ",$0)};NR%2==0{print ""}' FILE.txt

OUT :

LIN This is the value which I need from this line which has a very long line
SHR This1;This2; This3;
GYC This is an extra.
  • $1=$1 : excluir espaço da linha de início
  • printf("%s ",$0) delete \n ( newline ) do final da linha
  • NR%2==0{print ""} print \n ( newline ) para linhas pares (por exemplo: 2,4,6, ...)
por 01.09.2017 / 18:15
1
/^[A-Z]/        { if (line) { print line }; line =      $0 }
/^ /            { sub(/     /, "")        ; line = line $0 }
END             { if (line) { print line }                 }

Este script awk produzirá

LIN This is the value which I need from this line which has a very long line
SHR This1;This2;This3;
GYC This is an extra.

dados os dados fornecidos na pergunta em file.in .

  1. O primeiro bloco será executado para cada linha que começar com um caractere ASCII maiúsculo. Ele produzirá o conteúdo de line se houver algo nele e, em seguida, salvará a linha de entrada atual em line . Isso cuida da saída da linha construída para o "bloco" de entrada anterior e começa a montar a próxima linha de saída.

  2. O segundo bloco será executado para cada linha que tenha pelo menos um espaço no início e removerá os primeiros cinco espaços antes de adicioná-lo ao final de line . Isso constrói a linha de saída a partir das linhas de continuação na entrada.

  3. O bloco END emitirá o line salvo se houver algo nele. Isso cuida da saída da linha montada do "bloco" final de entrada.

Você executa isso com

$ awk -f script.awk file.in

Esse script manipula os casos em que pode haver várias linhas recuadas (continuadas).

    
por 01.09.2017 / 16:09