web-dev-qa-db-fra.com

shell remplacer cr \ lf par une virgule

J'ai input.txt

1
2
3
4
5

J'ai besoin d'obtenir un tel output.txt

1,2,3,4,5

Comment faire?

42
vinnitu

Essaye ça:

tr '\n' ',' < input.txt > output.txt
64
eumiro

Avec sed, vous pouvez utiliser:

sed -e 'H;${x;s/\n/,/g;s/^,//;p;};d'

H ajoute l'espace modèle à l'espace d'attente (sauvegarde de la ligne actuelle dans l'espace d'attente). Le ${...} entoure les actions qui s'appliquent uniquement à la dernière ligne. Ces actions sont: x swap hold et pattern space; s/\n/,/g remplacer les sauts de ligne intégrés par des virgules; s/^,// supprime la virgule de début (il y a une nouvelle ligne au début de l'espace d'attente); et p print. d supprime l'espace du motif - pas d'impression.

Vous pouvez également utiliser, par conséquent:

sed -n -e 'H;${x;s/\n/,/g;s/^,//;p;}'

Le -n supprime l'impression par défaut afin que le d final ne soit plus nécessaire.

Cette solution suppose que les fins de ligne CRLF sont la fin de ligne native locale (vous travaillez donc sous DOS) et que sed générera donc la fin de ligne native locale dans l'opération d'impression. Si vous avez une entrée au format DOS mais que vous souhaitez une sortie au format Unix (LF uniquement), vous devez travailler un peu plus dur - mais vous devez également le stipuler explicitement dans la question.

Cela a bien fonctionné pour moi sur MacOS X 10.6.5 avec les nombres 1..5, 1..50 et 1..5000 (23 893 caractères sur la seule ligne de sortie); Je ne suis pas sûr que je voudrais pousser plus fort que ça.

18
Jonathan Leffler

En réponse au commentaire de @ Jonathan à la réponse de @ eumiro:

tr -s '\r\n' ',' < input.txt | sed -e 's/,$/\n/' > output.txt
11
glenn jackman

tr et sed utilisés sont très bons mais en ce qui concerne l'analyse de fichiers et l'expression régulière, vous ne pouvez pas battre Perl (Je ne sais pas pourquoi les gens pensent que sed et tr sont plus proches de Shell que Perl .. .)

Perl -pe 's/\n/$1,/' your_file

si vous voulez que Shell le fasse, regardez la correspondance des chaînes

${string/#substring/replacement}
10
Arnaud
  • Versions awk:
    • awk '{printf("%s,",$0)}' input.txt
    • awk 'BEGIN{ORS=","} {print $0}' input.txt
    • Sortie - 1,2,3,4,5,

Puisque vous avez demandé 1,2,3,4,5, Par rapport à 1,2,3,4,5, (Notez la virgule après 5, la plupart des solutions ci-dessus incluent également la virgule de fin), voici deux autres versions avec Awk (avec wc et sed) pour se débarrasser de la dernière virgule:

  • i='input.txt'; awk -v c=$(wc -l $i | cut -d' ' -f1) '{printf("%s",$0);if(NR<c){printf(",")}}' $i

  • awk '{printf("%s,",$0)}' input.txt | sed 's/,\s*$//'

7
gsbabil

Utilisez la commande coller. Voici l'utilisation de tuyaux:

echo "1\n2\n3\n4\n5" | paste -s -d, /dev/stdin

Voici en utilisant un fichier:

echo "1\n2\n3\n4\n5" > /tmp/input.txt
paste -s -d, /tmp/input.txt

Par pages de manuel, le s concatène toutes les lignes et d permet de définir le caractère de délimitation.

4
Nestor Urquiza
cat input.txt | sed -e 's|$|,|' | xargs -i echo "{}"
1
Noel Yap
  • version python:

    python -c 'import sys; print(",".join(sys.stdin.read().splitlines()))'

N'a pas le problème de virgule de fin (parce que join fonctionne de cette façon) et splitlines divise les données sur les fins de ligne natives (et les supprime).

1
qneill