Concatenar archivos e insertar una nueva línea entre archivos


127

Tengo varios archivos con los que quiero concat cat. Digamos

File1.txt 
foo

File2.txt
bar

File3.txt
qux

Quiero concat para que el archivo final se vea así:

foo

bar

qux

En lugar de esto con lo habitual cat File*.txt > finalfile.txt

foo
bar 
qux

¿Cuál es la forma correcta de hacerlo?


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

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

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

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

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)

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.


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.