Pregunta sobre loops, shell, bash, linux, gzip – Cómo gzip todos los archivos en todos los subdirectorios en bash

20

Quiero iterar entre los subdirectorios de mi ubicación actual y gzip cada archivo por separado. Para comprimir archivos en un directorio, uso

<code>for file in *; do gzip "$file"; done
</code>

pero esto solo puede funcionar en el directorio actual y no en los subdirectorios del directorio actual. ¿Cómo puedo reescribir las declaraciones anteriores para que también comprima los archivos en todos los subdirectorios?

Tu respuesta

3   la respuesta
5
<code>find . -type f | while read file; do gzip "$file"; done
</code>
@ c00kiemon5ter ¿Una respuesta que funciona, pero puede estar incompleta, merece un voto negativo? De acuerdo con SO "Use sus votos negativos cada vez que encuentre una publicación extremadamente descuidada, sin esfuerzo, o una respuesta que sea clara y quizás peligrosamente incorrecta". Esta respuesta no es ninguna de esas cosas. Incompleto, algo descuidado, pero no incorrecto. Probablemente deberías haber dejado que el proceso de upvote pasara factura y dejar un comentario. Tim Pote
¿Qué pasa si un archivo contiene espacios u otros caracteres especiales? que no funciona confor ahí c00kiemon5ter
Imo, la respuesta es incorrecta. Farshid nunca especificó que los archivos no contienen caracteres especiales, por lo que su respuesta solo responde a un caso especial de la pregunta. Eres mejor de usarfind .. | while read ... Corrija su respuesta y seré el primero en votar. Pero no me pidas que promueva respuestas incorrectas (imo). c00kiemon5ter
Debido a que su respuesta fue más correcta e inexplicablemente la ha eliminado, he cambiado mi respuesta para que sea la suya. Solo tenga en cuenta que "no promocionar" no significa necesariamente una votación negativa. Habría alterado mi respuesta o la habría borrado solo después de su comentario. Tim Pote
50

No hay necesidad de bucles ni nada más quefind ygzip:

<code>find . -type f ! -name '*.gz' -exec gzip "{}" \;
</code>

Esto encuentra todos los archivos regulares en y debajo del directorio actual cuyos nombres no terminan con el.gz extensión (es decir, todos los archivos que aún no están comprimidos). Invocagzip en cada archivo individualmente.

Editar, basado en el comentario deuser unknown:

Los frenillos ({}) se reemplazan con el nombre del archivo, que se pasa directamente, como una sola palabra, al comando siguiente-exec Como puedes ver aquí:

<code>$ touch foo
$ touch "bar baz"
$ touch xyzzy
$ find . -exec echo {} \;

./foo
./bar baz
./xyzzy
</code>
+1 para los archivos exclude * .gz GuruM
Su última oración es una desinformación común. Find sabe dónde comienza un nombre de archivo y dónde termina. En sí mismo, no tiene ningún problema con espacios en blanco o saltos de línea y otras cosas divertidas. Entonces `-exec gzip {}` llama a gzip con un solo nombre de archivo, y como no se invoca un shell intermedio, lo que podría interpretar un espacio en blanco como delimitador, gzip recibirá el nombre de archivo completo. La sugerencia en la página del manual de find parece estar desactualizada y significa: tu shell podría intentar interpretar {} antes de pasarla a buscar, pero no se ha visto una shell de este tipo.durante años. user unknown
Tu aprendes algo nuevo cada dia. Gracias por la lección! Adam Liss
27

preferiríagzip -r ./ Lo que hace lo mismo pero es más corto.

¿No debería ser la mejor respuesta ...? GyuHyeon Choi

Preguntas relacionadas