Concatenar archivos e insertar una nueva línea entre archivos

Respuestas:

121

Tu puedes hacer:

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

Asegúrese de que el archivo finalfile.txtno existe antes de ejecutar el comando anterior.

Si se le permite usar awk, puede hacer:

awk 'FNR==1{print ""}1' *.txt > finalfile.txt
codictorio
fuente
10
AWK '{print $0}' *.txt
Timger
77
Esto tiene el defecto distintivo de que habrá líneas vacías al final (desde la primera alternativa) o al principio (segunda alternativa). Sin awk 'FNR==1 && NR > 1 ...'embargo, puedes protegerte fácilmente contra esto .
tripleee
55
Si coloca >finalfile.txtdespués done, puede sobrescribir en lugar de agregar, lo que eliminará el requisito de asegurarse de que el archivo falta o está vacío antes del ciclo.
tripleee
53

Si tiene pocos archivos suficientes para enumerar cada uno, puede usar la sustitución de procesos en Bash, insertando una nueva línea entre cada par de archivos:

cat File1.txt <(echo) File2.txt <(echo) File3.txt > finalfile.txt
Robert Tupelo-Schneck
fuente
1
¡Hermoso! Gracias.
Bob Kocisko
Esto funcionó muy bien para mis certificados Letsencrypt para crear archivos .pem.
leeman24
35

Si fuera yo quien lo haría, usaría sed:

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

En este patrón sed $ tiene dos significados, primero coincide con el último número de línea (como un rango de líneas para aplicar un patrón) y segundo coincide con el final de la línea en el patrón de sustitución.

Si su versión de sed no tiene -s(procesar archivos de entrada por separado), puede hacerlo todo como un bucle:

for f in *.txt ; do sed -e '$s/$/\n/' $f ; done > finalfile.txt
Flexo
fuente
3
O en GNU sed:sed -s '$G' *.txt > finalfile.txt
Ruud Helderman
¡Solo una transmisión! ¡Esta debería ser la respuesta aceptada!
Yassine ElBadaoui
tengan cuidado chicos, acabo de estrellar mi PC porque lo usé finden lugar del *.txt, lo que significa que el archivo se adjuntó a sí mismo.
Xerus
11

Puede hacerlo usando xargssi lo desea, pero la idea principal sigue siendo la misma:

find *.txt | xargs -I{} sh -c "cat {}; echo ''" > finalfile.txt
Nick Roz
fuente
1
Gracias. Me resulta xargsmucho más fácil de usar que los bucles en bash.
RawwrBag
9

Esto funciona en Bash:

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

A diferencia de las respuestas con >>(agregar), la salida de este comando se puede canalizar a otros programas.

Ejemplos:

  • for f in File*.txt; do cat $f; echo; done > finalfile.txt
  • (for ... done) > finalfile.txt (Parens son opcionales)
  • for ... done | less (entubado en menos)
  • for ... done | head -n -1 (esto elimina la línea en blanco al final)
usuario3780389
fuente
7

Así es como lo hice en OsX 10.10.3

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

dado que el simple comando 'echo' sin parámetros terminó en ninguna nueva línea insertada.

lbrutti
fuente
Esto coloca la cadena al final del archivo; ¿Cómo lo inserto entre cada archivo?
onassar
3

En python, esto se concatena con líneas en blanco entre los archivos ( ,suprime la adición de una línea en blanco final adicional):

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

Aquí está el feo python one-liner que se puede llamar desde el shell e imprime la salida en un archivo:

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