¿Cómo concatenar archivos de diferentes subdirectorios?

¿Cómo concatenar archivos de diferentes subdirectorios?

Tengo una carpeta grande que contiene muchos subdirectorios, cada uno con muchos .txtarchivos. Quiero concatenar todos estos archivos en un solo .txtarchivo. Puedo hacerlo para cada uno de los subdirectorios con cat *.txt>merged.txt, pero intento hacerlo para todos los archivos de la carpeta grande. ¿Cómo hago esto?

Respuesta1

prueba con

find /path/to/source -type f -name '*.txt' -exec cat {} + >mergedfile

busque todos los archivos '*.txt' fde /path/to/sourceforma recursiva para los subdirectorios y concatenelos todos en uno mergedfile.

Para concatenar los archivos de cada subdirectorio dentro de su directorio, haga:

find . -mindepth 1 -type d -execdir sh -c 'cat $1/*.txt >> $1/mergedfile' _ {} \;

Respuesta2

Si está utilizando Bash y la cantidad de archivos de texto está contenida (es decir, no excede el límite máximo de número de argumentos, que es muy grande pero no infinito), puede lograrlo fácilmente con la globstarfunción:

$ shopt -s globstar
$ cat **/*.txt > merged.txt

Un enfoque más general, aunque menos elegante, será utilizarlo findcomo controlador y hacer que llame cata cada archivo, añadiendo el resultado:

$ find -name \*.txt -exec sh -c 'cat {} >> merged.out' \;

Es necesario realizar una llamada shaquí porque desea agregar el resultado de cada uno cat. Asegúrese de que el archivo de salida tenga una extensión diferente o se encuentre fuera del árbol que está fusionando, o findpuede intentar concatenar la salida consigo mismo.

Respuesta3

Si tiene que realizar la concatenación en un orden particular, lo siguiente concatenará los archivos en orden lexicográfico (ordenados por nombres de ruta) en bash:

shopt -s globstar
for name in **/*.txt; do
    [ -f "$name" ] && cat <"$name"
done >merged.out

Esto es similar al findcomando

find  . -type f -name '*.txt' -exec cat {} ';' >merged.out

excepto que el orden puede ser diferente, se incluirían enlaces simbólicos a archivos normales (agregue un && [ ! -L "$name" ]si no los desea) y se excluirían los archivos ocultos (y los archivos en directorios ocultos) (úselos shopt -s dotglobpara volver a agregarlos).

información relacionada