linux - more - Concatenar archivos e insertar nueva línea entre archivos
concatenar varios archivos en uno linux (7)
Así es como lo hice en OsX 10.10.3
for f in *.txt; do (cat $f; echo '''') >> fullData.txt; done
ya que el simple comando ''echo'' sin params terminó en ninguna nueva línea insertada.
Tengo varios archivos que quiero concat con 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 el cat File*.txt > finalfile.txt
habitual cat File*.txt > finalfile.txt
foo
bar
qux
¿Cuál es la forma correcta de hacerlo?
En python, esto se concatena con líneas en blanco entre los archivos (el ,
suprime la adición de una línea en blanco adicional):
print ''/n''.join(open(f).read() for f in filenames),
Aquí está el one-liner feo de pitón que se puede invocar desde el shell e imprime el resultado en un archivo:
python -c "from sys import argv; print ''/n''.join(open(f).read() for f in argv[1:])," File*.txt > finalfile.txt
Esto funciona en Bash:
for f in *.txt; do cat $f; echo; done
A diferencia de las respuestas con >>
(anexar), 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
for ... done | less
(tubería en menos) -
for ... done | head -n -1
for ... done | head -n -1
(esto quita la línea en blanco al final)
Puedes hacerlo usando xargs
si quieres, pero la idea principal sigue siendo la misma:
find *.txt | xargs -I{} sh -c "cat {}; echo ''''" > finalfile.txt
Si fuera yo el que 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 en segundo lugar coincide con el final de la línea en el patrón de sustitución.
Si su versión de sed no tiene -s
(procesa archivos de entrada por separado), puede hacerlo todo como un bucle:
for f in *.txt ; do sed -e ''$s/$//n/'' $f ; done > finalfile.txt
Si tiene pocos archivos suficientes que pueda 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
Tu puedes hacer:
for f in *.txt; do (cat "${f}"; echo) >> finalfile.txt; done
Asegúrese de que el archivo finalfile.txt
no exista antes de ejecutar el comando anterior.
Si puede usar awk
, puede hacer lo siguiente:
awk ''FNR==1{print ""}1'' *.txt > finalfile.txt