2011-11-18 6 views
66

Ho più file che desidero concatenare con cat. DiciamoConcatenazione di file e inserimento di una nuova riga tra file

File1.txt 
foo 

File2.txt 
bar 

File3.txt 
qux 

voglio concat in modo che il file finale assomiglia a:

foo 

bar 

qux 

Invece di questo con solita cat File*.txt > finalfile.txt

foo 
bar 
qux 

Qual è il modo giusto per farlo?

+2

possibile duplicato di [Come faccio a includere una riga vuota tra i file che sto concatenare wi th "cat"?] (http://stackoverflow.com/questions/1653063/how-do-i-include-a-blank-line-between-files-im-concatenating-with-cat) – legoscia

risposta

63

si può fare:

for f in *.txt; do (cat "${f}"; echo) >> finalfile.txt; done 

assicurarsi che il file finalfile.txt non esiste prima di eseguire il comando precedente.

Se si è permesso di utilizzare awk si può fare:

awk 'FNR==1{print ""}1' *.txt > finalfile.txt 
+3

'AWK '{ stampa $ 0} '* .txt' – timger

+3

con 'AWK' intendi' awk', giusto? –

+5

Questo ha il chiaro difetto che ci saranno linee vuote alla fine (dalla prima alternativa) o all'inizio (seconda alternativa). Puoi facilmente evitare questo con 'awk 'FNR == 1 && NR> 1 ...'' invece, comunque. – tripleee

21

Se fosse me farlo userei sed:

sed -e '$s/$/\n/' -s *.txt > finalfile.txt 

In questo modello sed $ ha due significati, in primo luogo corrisponde solo all'ultimo numero di linea (come un intervallo di linee per applicare un motivo) e in secondo luogo corrisponde alla fine della linea nel modello di sostituzione.

Se la versione di sed non ha (file separatamente ingresso di processo) -s si può fare tutto come un ciclo se:

for f in *.txt ; do sed -e '$s/$/\n/' $f ; done > finalfile.txt 
+2

Oppure in GNU sed: 'sed -s '$ G' * .txt> finalfile.txt' –

+0

Solo un flusso! questa dovrebbe essere la risposta accettata! –

24

Se si dispone di pochi file sufficiente che si può elencare ciascuno di essi, quindi è possibile utilizzare process substitution in Bash, l'inserimento di una nuova linea tra ogni coppia di file:

cat File1.txt <(echo) File2.txt <(echo) File3.txt > finalfile.txt 
+0

Bello! Grazie. –

6

Ecco come ho appena fatto su OSX 10.10.3

for f in *.txt; do (cat $f; echo '') >> fullData.txt; done 

poiché il semplice comando "echo" senza parametri terminato in nessuna nuova riga inserita.

4

Questo funziona in Bash:

for f in *.txt; do cat $f; echo; done 

In contrasto con risposte >> (accodare), l'uscita di questo comando può essere convogliata in altri programmi.

Esempi:

  • for f in File*.txt; do cat $f; echo; done > finalfile.txt
  • (for ... done) > finalfile.txt (parentesi sono opzionali)
  • for ... done | less (tubazioni in meno)
  • for ... done | head -n -1 (puo strisce sulla linea vuota finale)
3

In Python, questo concatena con linee vuote tra file (i , sopprime l'aggiunta di una riga vuota finale):

print '\n'.join(open(f).read() for f in filenames), 

Ecco il pitone one-liner brutta che può essere chiamato dal guscio e stampa l'output in un file:

python -c "from sys import argv; print '\n'.join(open(f).read() for f in argv[1:])," File*.txt > finalfile.txt 
3

si può farlo utilizzando xargs se ti piace, ma l'idea principale è sempre la stessa:

find *.txt | xargs -I{} sh -c "cat {}; echo ''" > finalfile.txt 
+0

Grazie. Trovo 'xargs' molto più facile da usare rispetto ai loop in bash. – RawwrBag

Problemi correlati