Divide a linha única em várias linhas, o caractere Newline ausente para todas as linhas no arquivo de entrada [duplicado]

3

Existe uma maneira de dividir uma linha em várias linhas com 3 colunas. Novos caracteres de linha estão faltando no final de todas as linhas no arquivo.

Eu tentei usar o awk, mas ele está dividindo cada coluna como uma linha, em vez de três colunas em cada linha.

awk '{ gsub(",", "\n") } 6' filename

onde o conteúdo de filename se parece com:

A,B,C,D,E,F,G,H,I,J,K,L,M,N,O

A saída desejada tem 3 colunas em cada linha:

A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
    
por Rakesh K 16.03.2018 / 05:58

2 respostas

6

Usando awk

$ awk -v RS='[,\n]' '{a=$0;getline b; getline c; print a,b,c}' OFS=, filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

Como funciona

  • -v RS='[,\n]'

    Isto diz ao awk para usar qualquer ocorrência de uma vírgula ou uma nova linha como um separador de registro.

  • a=$0; getline b; getline c

    Isso diz ao awk para salvar a linha atual na variável a , a próxima linha em variável b e a próxima linha depois disso na variável c .

  • print a,b,c

    Isso diz ao awk para imprimir a , b e c

  • OFS=,

    Isto diz ao awk para usar uma vírgula como separador de campos na saída.

Usando tr e paste

$ tr , '\n' <filename | paste -d, - - -
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

Como funciona

  • tr , '\n' <filename

    Isso lê o nome do arquivo ao converter todas as vírgulas em novas linhas.

  • paste -d, - - -

    Este paste para ler três linhas de stdin (uma para cada - ) e colá-las juntas, cada uma separada por uma vírgula ( -d, ).

awk alternativo

$ awk -v RS='[,\n]' '{printf "%s%s",$0,(NR%3?",":"\n")}' filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

Como funciona

  • -v RS='[,\n]'

    Isto diz ao awk para usar qualquer ocorrência de uma vírgula ou uma nova linha como um separador de registro.

  • printf "%s%s",$0,(NR%3?",":"\n")

    Isso diz ao awk para imprimir a linha atual, seguida por uma vírgula ou uma nova linha, dependendo do valor do número da linha atual, NR , módulo 3.

por 16.03.2018 / 06:33
4
sed 's/\(\([^,]\+,\)\{3\}\)/\n/g;s/,\n/\n/g' filename

Eu sei que você pediu uma solução awk , e agora vou tentar enviar isso como uma edição para esta resposta, mas para mim uma solução sed foi mais simples ... ... e o usuário john1024 bati-me nisso, com uma solução awk . Veja lá. Sua solução paste e tr é provavelmente a mais clássica resposta unix-ish.

  1. Esta solução usa os recursos de regex estendidos do GNU sed.

  2. \(..\) é um grupo de coleções regex. Observe que a solução usa dois, um aninhado dentro do outro.

  3. [^,]+, é qualquer string que não tenha uma vírgula, seguida por uma vírgula. No seu caso, uma coluna ou campo.

  4. \{3\} é um multiplicador de expressão regular, indicando a utilização da expressão regex anterior três vezes.

  5. é uma referência anterior à regex. para o regex anterior.

  6. g significa fazer isso para todas as instâncias na linha.

  7. s/,\n/\n/g remove a vírgula final. É necessário incluir o caractere de nova linha aqui, porque sed ainda está considerando a entrada como uma única linha.

por 16.03.2018 / 06:25