¿Cómo tar ciertos tipos de archivos en todos los subdirectorios?

83

Quiero tar y todos los archivos .php y .html en un directorio y sus subdirectorios. Si uso

tar -cf my_archive *

alquila todos los archivos, que no quiero. Si uso

tar -cf my_archive *.php *.html

ignora los subdirectorios. ¿Cómo puedo convertirlo en tar de forma recursiva pero incluir solo dos tipos de archivos?

usuario1566515
fuente

Respuestas:

143

find ./someDir -name "*.php" -o -name "*.html" | tar -cf my_archive -T -

DeeDee
fuente
@DeeDee ¿Existe alguna limitación en la cantidad de archivos, etc.?
user1566515
1
@DeeDee - no, lo que quise decir es que no necesitas los parens.
Mike Makuch
@ user1566515 Puede haber algún límite de sistema de archivos o límite de espacio general que pondría un límite superior en su archivo tar. Eso depende enteramente de su propio sistema. De lo contrario, la tubería esencialmente creará el archivo tar sobre la marcha, por lo que no estará limitado por el número o tamaño del archivo.
DeeDee
¡Gracias! ... ¿cómo agregar más de 2 condiciones / tipo de archivo?
gluuke
5
@gluuke uso -o -name [pattern]para cada nueva condición
DeeDee
15

Si está utilizando la bashversión> 4.0, puede aprovechar shopt -s globstarpara hacer un trabajo rápido de esto:

shopt -s globstar; tar -czvf deploy.tar.gz **/Alice*.yml **/Bob*.json

esto agregará todos los archivos .yml que comienzan con Alice desde cualquier subdirectorio y agregará todos los archivos .json que comiencen con Bob desde cualquier subdirectorio.

Sairam Krish
fuente
2
La única respuesta que solo usa alquitrán, la mejor respuesta en mi opinión.
Simon
2
A pesar de la impresión de glob '**' para el directorio, este comando no se ejecuta de forma recursiva (ninguna sub-subcarpeta)
Eddie
@Eddie ** debería funcionar. puede haber algo diferente con sus parámetros. También verifique si hay algún espacio en el nombre de la carpeta que pasa en la línea de comando. Si no es así, ¿puede pegar su comando real?
Sairam Krish
'**' es evaluado por el shell antes de llegar al comando y solo se ve como 2 independientes * que se resuelve en 0 o caracteres, no tiene funcionalidad recursiva para abarcar directorios tldp.org/LDP/GNU-Linux-Tools-Summary/ html / x11655.htm
Eddie
2
@eddie sí, es evaluado por shell, aunque bash> 4.0 tiene una shopt -s globstaropción, por lo que la respuesta es correcta y en realidad es la mejor
Roman Usherenko
13

Un método es:

tar -cf my_archive.tar $( find -name "*.php" -or -name "*.html" )

Sin embargo, hay algunas advertencias con este método:

  1. Fallará si hay archivos o directorios con espacios en ellos, y
  2. fallará si hay tantos archivos que la longitud máxima de la línea de comandos está completa.

Una solución a esto podría ser generar el contenido del comando de búsqueda en un archivo y luego usar la opción "-T, --files-from FILE" para tar.

Robin Sheat
fuente
1) Por "fallar", ¿quiere decir que los archivos con espacios se omitirán o que no se creará el archivo tar? 2) Tengo alrededor de 100K archivos. ¿Está por encima de la longitud máxima de la línea de comando?
user1566515
1
1. Creará el archivo, pero informará los archivos que faltan. 2. Eso será demasiado, supongo. Dado esto, sería mejor usar un método como @DeeDee sugiere a continuación, solucionará estos problemas bastante bien.
Robin Sheat
3

Esto manejará caminos con espacios:

find ./ -type f -name "*.php" -o -name "*.html" -exec tar uvf myarchives.tar {} +
Ian Reinhart Geiser
fuente
0

Ponlos en un archivo

find . \( -name "*.php" -o -name "*.html" \) -print > files.txt

Luego use el archivo como entrada para tar, use -I o -T dependiendo de la versión de tar que use

Utilice h para copiar enlaces simbólicos

tar cfh my.tar -I files.txt 
Noam Geffen
fuente
0

find ./ -type f -name "*.php" -o -name "*.html" -printf '%P\n' |xargs tar -I 'pigz -9' -cf target.tgz

para multinúcleo o solo para un núcleo:

find ./ -type f -name "*.php" -o -name "*.html" -printf '%P\n' |xargs tar -czf target.tgz

dmitry_podyachev
fuente
-2
tar -cf my_archive `find ./ | grep '.php\|.html'`

Utilice "buscar" y "grep" para obtener todas las rutas de los archivos .php y .html en todos los directorios y sus subdirectorios. Luego, pase esa información de ruta a tar para comprimirla.

Tenga cuidado con los símbolos "y". Tenga en cuenta también que esto alcanzará el límite de cuántos caracteres permitirá su shell en la línea de comando, a diferencia de algunas de las otras respuestas.

Trent Huang
fuente