awk-Imprimindo o valor da coluna sem nova linha e adicionando vírgula

3

input.txt

 EN1
 EN2
 EN3
 EN4
 EN5

saída

EN1,EN2,EN3,EN4,EN5

Eu tentei o awk.Mas não está imprimindo com vírgula

awk 'BEGIN { OFS = ","} { printf $1}' input.txt

Eu tenho a versão GNU Awk 4.0.0

    
por jack 03.08.2012 / 23:29

6 respostas

5
awk 'BEGIN{ORS=","}1' input.txt

produz isso:

EN1,EN2,EN3,EN4,EN5,

então está imprimindo com uma vírgula (então não tenho certeza se entendi seu comentário em seu post sobre isso não estar acontecendo) embora eu suspeite que a vírgula final seja um problema.

Testado com o GNU Awk 3.1.7

    
por 03.08.2012 / 23:32
4

Você pode usar tr em tal situação.

tr '\n' ',' <input.txt

Isso substitui a nova linha final por uma vírgula também. Para evitar isso, no Linux, se você sabe que o arquivo de entrada termina com uma nova linha:

<input.txt head -c -1 | tr '\n' ,

Adicione ; echo se quiser que a saída seja terminada por uma nova linha.

Como alternativa, você pode obter o shell para remover uma vírgula à direita, se houver uma.

columns=$(<input.txt tr '\n' ',')
echo "${columns%,}"
    
por 03.08.2012 / 23:55
3

Há também xargs e sed :

$ xargs <input.txt | sed -e 's/ /,/g'
EN1,EN2,EN3,EN4,EN5

Uma vantagem aqui é que não há uma vírgula à direita para se livrar.

xargs para combinar as linhas de entrada, sed para substituir todos os espaços por vírgulas. Eu uso isso rotineiramente para construir expressões regulares (substituir espaços com | ) e somas rápidas para pipe em bc (substituir espaços com + ).

(FYI xargs é padronizado como echo como o comando, se nenhum for fornecido)

NOTA: Isso só funciona se o arquivo de entrada for como descrito (um campo por linha, sem espaços). Se houver mais campos e / ou espaços na entrada, você poderá usar o awk ou o sed para pré-processar a entrada. Por exemplo, com entradas como esta:

EN1 foo bar
EN2 bar foo
EN3 baz quux
EN4 abc def
EN5 hij klm

Aqui o awk é usado para extrair apenas o primeiro campo:

$ awk '{print $1}' input.txt | xargs | sed -e 's/ /,/g'
EN1,EN2,EN3,EN4,EN5

Neste segundo exemplo (sed), os espaços na entrada original são substituídos por alguma outra string (escolhida como não sendo provável na entrada original), então alimentada em xargs. sed, em seguida, substitui os espaços adicionados por xargs e, em seguida, restaura as seqüências de caracteres da entrada:

$ sed -e 's/ /--space--/g' input.txt | xargs | sed -e 's/ /,/g' -e 's/--space--/ /g'
EN1 foo bar,EN2 bar foo,EN3 baz quux,EN4 abc def,EN5 hij klm

Agora, para alguns comentários gratuitos sobre artigos de opinião:

Um dos conhecimentos mais úteis sobre ferramentas de processamento de texto unix é que você pode e deve pensar que os dados são quase infinitamente maleáveis - você pode transformá-los na forma que precisar, seja para fornecer informações a outro processo ou para produzir a saída que você quer ou ambos.

Isso é parte da razão pela qual as pessoas unix tendem a odiar formatos de dados proprietários - não é apenas uma desaprovação filosófica ou um desejo de evitar o aprisionamento de fornecedores, é também o fato muito pragmático de que eles dificultam manipular e usar nossos dados de maneiras que não foram previstas pelos desenvolvedores do software.

    
por 04.08.2012 / 03:13
3

Eu sei, tópico antigo, mas eu não pude resistir - aqui está outra forma simples e curta de fazer isso:

$ paste -sd, input.txt
EN1,EN2,EN3,EN4,EN5
$

Funciona no Linux e no Solaris, talvez até em outras plataformas.

    
por 09.12.2014 / 17:43
2

Uma solução que não imprime uma vírgula no final da linha:

{printf("%s", NR == 1 ? $0 : ","$0);} END {printf("\n");} file

Explicação

Quando a primeira linha é vista ( NR == 1 ), apenas é impressa; caso contrário, uma vírgula e a linha serão enviadas como argumentos para printf .

Esta solução usa o operador ternário AWK ?: , ou seja:

NR == 1 ? $0 : ","$0

Se a variável NR for igual a 1 , ela enviará a primeira linha como o argumento para printf ; senão envia uma vírgula concatenada com a linha atual.

    
por 12.03.2016 / 06:40
1
perl -pe '(eof)?s/\s+$//:s/\s+$/,/' input.txt  

output: sem \n

EN1,EN2,EN3,EN4,EN5
    
por 04.08.2012 / 02:13