Concatenazione di file e inserimento di una nuova riga tra file

Ho più file che voglio concatcare con cat . Diciamo

 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 il solito cat File*.txt > finalfile.txt

 foo bar qux 

Qual è il modo giusto per farlo?

Tu puoi fare:

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

Assicurati che il file finalfile.txt non esista prima di eseguire il comando precedente.

Se ti è permesso usare awk puoi fare:

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

Se si dispone di un numero di file sufficiente da elencarli, è ansible utilizzare la sostituzione del processo in Bash, inserendo una nuova riga tra ogni coppia di file:

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

Se dovessi 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 tua versione di sed non ha -s (process input files separatamente) puoi fare tutto come un ciclo:

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

È così che l’ho fatto su OsX 10.10.3

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

poiché il semplice comando “echo” senza parametri finiva in nessuna nuova riga inserita.

Questo funziona in Bash:

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

A differenza delle risposte con >> (append), l’output di questo comando può essere inviato in altri programmi.

Esempi:

  • for f in File*.txt; do cat $f; echo; done > finalfile.txt
  • (for ... done) > finalfile.txt (i (for ... done) > finalfile.txt sono facoltativi)
  • for ... done | less for ... done | less (piping in meno)
  • for ... done | head -n -1 for ... done | head -n -1 (questo toglie la riga vuota finale)

Puoi farlo usando xargs se vuoi, ma l’idea principale è sempre la stessa:

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

In Python, questo concatena con linee vuote tra i file (il , sopprime l’aggiunta di una riga bianca finale in più):

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

Ecco il brutto one-liner Python che può essere chiamato dalla shell 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