Risposte:
Di seguito sono riportati una dozzina di esempi di come è possibile prendere un file come questo:
$ cat k.txt
1
2
3
e convertilo in questo formato:
1,2,3
Puoi usare questo comando per creare il file sopra se vuoi giocare insieme:
$ cat <<EOF > k.txt
1
2
3
EOF
Gli esempi seguenti sono divisi in 2 gruppi. Quelli che "funzionano" e quelli che "quasi" funzionano. Lascio questi perché spesso volte è altrettanto prezioso vedere perché qualcosa non funziona, come è vedere perché qualcosa funziona.
Sono rappresentati la maggior parte dei linguaggi di scripting con cui ho familiarità. Alcuni sono rappresentati più volte, poiché come nel famoso acronimo a cui si fa riferimento in Perl, TIMTOWTDI .
NOTA: è possibile sostituire la virgola ( ,
) negli esempi seguenti e sostituirla con qualsiasi carattere desiderato, ad es |
.
Questi frammenti di codice produrranno l'output desiderato.
Il paste
comando:
$ paste -s -d ',' k.txt
1,2,3
Il sed
comando:
$ sed ':a;N;$!ba;s/\n/,/g' k.txt
1,2,3
$ sed ':a;{N;s/\n/,/};ba' k.txt
1,2,3
Il perl
comando:
$ perl -00 -p -e 's/\n(?!$)/,/g' k.txt
1,2,3
$ perl -00 -p -e 'chomp;tr/\n/,/' k.txt
1,2,3
Il awk
comando:
$ awk '{printf"%s%s",c,$0;c=","}' k.txt
1,2,3
$ awk '{printf "%s,",$0}' k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
$ awk -vORS=, 1 k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
$ awk 'BEGIN {RS="dn"}{gsub("\n",",");print $0}' k.txt | awk '{sub(/\,$/,"");print}'
1,2,3
Il python
comando:
$ python -c "import sys; print sys.stdin.read().replace('\n', ',')[0:-1]" <k.txt
1,2,3
$ python -c "import sys; print sys.stdin.read().replace('\n', ',').rstrip(',')" <k.txt
1,2,3
Bash mapfile
integrato:
$ mapfile -t a < k.txt; (IFS=','; echo "${a[*]}")
1,2,3
Il ruby
comando:
$ ruby -00 -pe 'gsub /\n/,",";chop' < k.txt
1,2,3
$ ruby -00 -pe '$_.chomp!"\n";$_.tr!"\n",","' k.txt
1,2,3
Il php
comando:
$ php -r 'echo strtr(chop(file_get_contents($argv[1])),"\n",",");' k.txt
1,2,3
Avvertenze
La maggior parte degli esempi sopra funzionerà perfettamente. Alcuni hanno problemi nascosti, come l'esempio di PHP sopra. La funzione chop()
è in realtà un alias rtrim()
, quindi verranno rimossi anche gli spazi finali dell'ultima riga.
Lo stesso vale per il primo esempio di Ruby e il primo esempio di Python. Il problema è come stanno tutti usando un tipo di operazione che essenzialmente "taglia", alla cieca, un personaggio finale. Questo va bene nell'esempio fornito dall'OP, ma occorre fare attenzione quando si usano questi tipi di rivestimenti per assicurarsi che siano conformi ai dati che stanno elaborando.
Esempio
Pronuncia il nostro file di esempio, k.txt
assomiglia invece a questo:
$ echo -en "1\n2\n3" > k.txt
Sembra simile ma ha una leggera differenza. Non ha una nuova riga finale ( \n
) come il file originale. Ora quando eseguiamo il primo esempio di Python otteniamo questo:
$ python -c "import sys; print sys.stdin.read().replace('\n', ',')[0:-1]" <k.txt
1,2,
Questi sono gli esempi "sempre una damigella d'onore, mai una sposa" . Molti di essi potrebbero probabilmente essere adattati, ma quando si lavora su una potenziale soluzione a un problema, quando sembra "forzato", è probabilmente lo strumento sbagliato per il lavoro!
Il perl
comando:
$ perl -p -e 's/\n/,/' k.txt
1,2,3,
Il tr
comando:
$ tr '\n' ',' < k.txt
1,2,3,
I comandi cat
+ echo
:
$ echo $(cat k.txt)
1 2 3
Il ruby
comando:
$ ruby -pe '$_["\n"]=","' k.txt
1,2,3,
Bash's while
+ read
built-in:
$ while read line; do echo -n "$line,"; done < k.txt
1,2,3,
awk
preferisco un'alternativa più breve:awk -vORS=, 1 k.txt
bash
:mapfile -t a < k.txt; (IFS=','; echo "${a[*]}")
perl
e prima awk
li hai .
paste
quello in alto. Questo è esattamente ciò che paste -s
è qui. È un comando standard e sarebbe il più efficiente. Tutti gli altri sono eccessivi e / o non portatili o con limitazioni.
mapfile
è relativamente nuovo, aggiunto in bash
4.0.
@slm ha già dato una bella risposta, ma come domanda "formatta l'output di xargs"
xargs -I{} echo -n "{}|" < test.txt
-I
è l'opzione "sostituisci stringhe".{}
è un segnaposto per il testo di output.Se vuoi sbarazzarti del trailing |
puoi usare sed
per fare un po 'di pulizia:
$ xargs -I{} echo -n "{}|" < k.txt | sed -e 's/|$//'
1|2|3
tr
, sed
e anche altre ..
Questo è un vecchio thread, lo so. L'OP ha chiesto con un semplice codice come questo. Per tenerlo vicino all'originale, ho una soluzione semplice.
cat k.txt | xargs
1 2 3
usa sed
cat k.txt | xargs | sed 's/ /,/g'
1,2,3
o
cat k.txt | xargs | sed 's/ /|/g'
1|2|3
sed può sembrare un po 'strano ma scomposto, ha molto senso.
è per il sostituto. g 'è per globale: senza questo, farà solo la prima sostituzione su ogni nuova linea. Dato che usi 'xargs', li visualizza come una riga. Quindi otterrai "1,2 3".
Il delimitatore viene utilizzato per la separazione. Ho usato il carattere /. Un trucco interessante: puoi sostituire il delimitatore con quasi tutti gli altri personaggi, purché lo manteniamo nello stesso formato tra le virgolette. Quindi funzionerebbe anche ...
cat k.txt | xargs | sed 's# #,#g'
o
cat k.txt | xargs | sed 'sT T,Tg'
Ovviamente, l'utilizzo di determinati caratteri come delimitatore può creare confusione, quindi sii intelligente.
xargs <k.txt | tr \ \|
Non è necessario cat
- basta inserire l'input del file e - se non viene dato nessun altro comando - xargs
verrà trasmesso il suo formato predefinito - che è di un tipo con /bin/echo
's (senza interpretazioni di c-escape con barra rovesciata) .
xargs
eliminerà gli spazi bianchi testa / coda dal file di input e comprimerà altre sequenze di spazi bianchi in un singolo spazio. Ciò significa che mentre si passa il file tr
a xargs
come:
tr \\n \| <k.txt | xargs
... stampe ...
1|2|3|
... andando dall'altra parte e operando solo sulle argomentazioni che xargs
i delimiti spaziali fanno ...
1|2|3\n
... perché xargs
stampa la riga finale finale (come richiesto per un file di testo) , ma non viene tr
risposto in questo modo.
Si noti, tuttavia, che questa (o qualsiasi altra soluzione offerta qui) non tiene conto della xargs
quotazione in input. xargs
distribuirà letteralmente caratteri non-newline tra virgolette singole / doppie / con barra rovesciata in input, che possono esse stesse essere quotate come:
xargs <<\IN
1 2' 3'\' \'4
IN
1 2 3' '4
xargs cat -n
, ma è più facile se si tagliare i caratteri di nuova riga, questo può essere realizzato conecho $(cat)
,grep
oawk
(strisciare il modo per farlo).xargs
non andare bene per il tuo scopo attuale.