2011-01-04 4 views
27

ho input.txtshell sostituire cr lf da una virgola

1 
2 
3 
4 
5 

ho bisogno di ottenere tale output.txt

1,2,3,4,5 

Come fare?

+0

Quale fine riga deve avere l'output? Hai menzionato CR \ LF nella domanda - vuoi dire che hai un file di testo DOS? E l'output dovrebbe essere un file di testo DOS (quindi è necessario un CRLF finale)? –

risposta

46

Prova questo:

tr '\n' ',' <input.txt> output.txt 
+0

Questo riguarda le nuove righe; che dire dei ritorni a bordo? Potrebbe non esserci nulla da fare se l'utente è su DOS ed è un file di testo - le routine di input convertono CRLF in '\ n'. Più seriamente, forse, il codice sostituisce la nuova riga finale (CRLF) con una virgola. –

+8

Questa soluzione lascia una virgola alla fine: –

+0

proprio come una risposta alla domanda di Jonathon, ho dovuto sostituire ''\ n'' con'' \ r'' per il ritorno a capo. – TravisF

14

Con sed, è possibile utilizzare:

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

Il H aggiunge i pattern space allo spazio stiva (salvare la riga corrente nello spazio di attesa). Lo ${...} circonda azioni che si applicano solo all'ultima riga. Tali azioni sono: x attesa di mantenimento e spazio pattern; s/\n/,/g sostituisce newline incorporate con virgole; s/^,// elimina la virgola iniziale (c'è una nuova riga all'inizio dello spazio di attesa); e p stampa. Lo d elimina lo spazio pattern - nessuna stampa.

Si potrebbe anche usare, quindi:

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

Il -n sopprime la stampa di default in modo che il finale d non è più necessario.

Questa soluzione presuppone che le terminazioni di riga CRLF siano la fine della linea nativa locale (quindi si sta lavorando su DOS) e che sed genererà quindi la linea nativa locale che termina con l'operazione di stampa. Se si dispone di input in formato DOS ma si desidera l'output in formato Unix (solo LF), è necessario lavorare un po 'più a fondo, ma è anche necessario specificarlo esplicitamente nella domanda.

Ha funzionato correttamente per me su MacOS X 10.6.5 con i numeri 1..5 e 1..50 e 1..5000 (23.893 caratteri nella singola riga di output); Non sono sicuro di volerlo spingere di più.

+1

Un altro modo: 'sed -n ': a; N; $ {s/\ n /,/g; p}; ba'' (senza dover eliminare una virgola iniziale). –

6

In risposta a @ commento di Jonathan alla risposta di @ eumiro:

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

tr e sed usato essere molto buona, ma quando si tratta di presentare l'analisi e la regex non si può battere perl (non so perché la gente pensa che sed e tr siano più vicini al guscio di perl ...)

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

se si vuole pura shell per farlo poi guardare stringa corrispondenti versioni

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

Poiché hai chiesto 1,2,3,4,5, rispetto a 1,2,3,4,5, (nota la virgola dopo 5, la maggior parte delle soluzioni di cui sopra comprendono anche la virgola finale), qui ci sono altre due versioni con Awk (con wc e sed) per eliminare l'ultimo comma:

  • 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*$//'

0
cat input.txt | sed -e 's|$|,|' | xargs -i echo "{}" 
3

comando Usa pasta. Qui sta utilizzando tubi:

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

Qui sta usando un file:

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

Per pagine man s concatena tutte le linee e d permette di definire il carattere delimitatore.