Estoy tratando de comprimir todos los archivos en ubuntu que tienen la extensión de archivo .css, .html o .js. en un directorio superior y todos los subdirectorios. Quiero conservar los archivos originales y sobrescribir el archivo .gz, si ya existe.
Entonces, cuando tengo n archivos, quiero mantener estos n archivos y crear n archivos de archivo adicionales. No sólo uno.
Mi intento fue ejecutar un script que se vea así:
gzip -rkf *.css
gzip -rkf *.html
... one line for each file extension
Primero: necesito tener una línea en esa secuencia de comandos para cada extensión de archivo que quiero gzip. Eso está bien, pero espero encontrar una mejor manera
Segundo y más importante: no funciona. Aunque -r debería hacer el trabajo, los subdirectorios no cambian. El archivo gzip solo se crea en el directorio superior.
¿Que me estoy perdiendo aqui?
Por cierto: El siguiente es un error en la salida detallada, ¿verdad? Cuando se usa la opción -k y -v
-k, --keep keep (don't delete) input files
-v, --verbose verbose mode
El resultado detallado dice que reemplaza el archivo, aunque "reemplazar" significa que el archivo original no existe después del reemplazo. De todos modos, esto es solo lo de salida.
$ ls
index.html subdir1 testfile testfile.css.gz
javaclass.java subdir2 testfile.css
$ gzip -fkv *.css
testfile.css: 6.6% -- replaced with testfile.css.gz
$ ls
index.html subdir1 testfile testfile.css.gz
javaclass.java subdir2 testfile.css

-rFunciona según lo diseñado. Desde man gzip : recorre la estructura de directorios de forma recursiva. Si alguno de los nombres de archivo especificados en la línea de comando son directorios , gzip descenderá al directorio y comprimirá todos los archivos que encuentre allí (o los descomprimirá en el caso de gunzip). (énfasis mío)Respuestas:
puedes hacerlo con un bucle for para encontrar cada archivo y luego comprimirlo:
fuente
-ropción no funciona,-ky-festá funcionando, puedo usarlos así: para i infind | grep -E "\.css$|\.html$"; do gzip -vkf "$ i"; hecho``...`proporciona una cadena, no una lista.forusa el separador de campo interno ($IFS) para decidir dónde se debe dividir esa cadena. Por defecto, se divide en saltos de línea, pestañas y espacios, por lo que si tiene un archivo llamadonew style.css, los comandosgzip newygzip style.cssse ejecutarán.export IFS=$'\n'justo antes delforciclo.yo usaría
Cambie
nameainamesi desea hacer coincidir las extensiones entre mayúsculas y minúsculas (es decir, incluir.CSSy / o.HTMLextensiones). Puede omitir el/path/to/dirsi desea iniciar la búsqueda recursiva desde el directorio actual.fuente
--keepcambio, sí, hace que se retengan los archivos originales. Omítelo si desea que se eliminen una vez comprimidos.Para obtener la lista de archivos:
Y para comprimir todos esos archivos:
fuente
tarla lista de archivos como salidafind, en lugar de los archivos en sí mismos?-Topcióntarprocesa la entrada como nombres de archivo.Solía respuesta de steeldriver , pero me gusta para terminar con el
--besty--forceopciones.cden cualquier carpeta y escriba este código. Todos sus archivos coincidentes serán comprimidos.--bestpara obtener la mejor relación de compresión.--forcepara sobrescribir sin preguntar si ya hay un archivo comprimido.fuente
Puedes usar globstar.
Con la
globstaropción de shell habilitada, todo lo que necesita esgzip -vk **/*.{css,html}.El shell Bash tiene una
globstaropción que te permite escribir globos recursivos con**.shopt -s globstarlo habilita Pero es posible que no desee hacer eso para otros comandos que ejecute más tarde, por lo que puede ejecutarlo junto con sugzipcomando en una subshell .Este comando
gzipes todo.cssy.htmllos archivos en el directorio actual de cualquiera de sus subdirectorios, cualquiera de sus subdirectorios, etc., manteniendo los archivos originales (-k) y que lo que está haciendo (diciendo-v):Si desea hacer coincidir los nombres de archivo sin distinción entre mayúsculas y minúsculas para que se incluyan esas extensiones con algunas o todas las letras en mayúscula, también puede habilitar la
nocaseglobopción de shell:;separa los dos comandos, y el exterior()hace que se ejecuten en una subshell. Establecer una opción de shell en un subshell no hace que se establezca en el shell de llamada. Si no desea habilitarglobstarcontinuación, puede ejecutarshopt -s globstar; entonces puedes ejecutar el comando:Puede deshabilitar
globstarconshopt -u globstar. Puede verificar si está habilitado actualmente conshopt globstar.Cómo funciona
La clave de cómo funciona este
gzipcomando es que el shell realiza expansiones en él para producir una lista de cada archivo en la jerarquía del directorio con un nombre coincidente, luego pasa cada uno de estos nombres de archivo como argumentosgzip.**/*.{css,html}en**/*.css **/*.html.**debido aglobstar) cuyos nombres de archivo consisten en cualquier cosa (*) seguido del sufijo especificado (.csso.htmlen este caso).Esto no coincide con los archivos cuyos nombres comienzan con
.los que residen en directorios nombrados de esta manera. Probablemente no tenga dichos archivos HTML y CSS y, si los tiene, probablemente no quiera incluirlos. Pero si desea incluirlos, puede hacerlos coincidir explícitamente según sus necesidades. Por ejemplo, cambiar**/*.{css,html}a**/{,.}*.{css,html}incluye archivos que comienzan.mientras aún no buscan en carpetas que sí lo hacen.Si desea que se incluyan tanto los archivos cuyos nombres comiencen
.como los archivos en directorios cuyos nombres comiencen con., hay una forma más limpia y sencilla: habilitar ladotglobopción de shell.O si desea la coincidencia entre mayúsculas y minúsculas y la coincidencia de nombres de archivo que comienzan con
.:Es posible, aunque muy raro,
**expandirse a algo demasiado tiempo.Si tiene una gran cantidad de archivos nombrados de esta manera, esto puede fallar con un mensaje de error que explica que el shell no puede construir la línea de comando porque sería demasiado largo. (Incluso con miles de archivos, esto generalmente no es un problema).
gzipno será llamado en absoluto, por lo que no obtendrá un trabajo a medio hacer.Si ocurre este error, o si le preocupa, puede usarlo
findcon-exec, como lo describe steeldriver (con{} \;) o como lo describo a continuación (con{} +).Se puede usar
findcon la-execacción y+para la eficiencia.El
gzipcomando admite recibir nombres de varios archivos para comprimir. Pero estefindcomando, aunque funciona bien y no será lento a menos que tenga muchos archivos, ejecuta elgzipcomando una vez para cada archivo:Esto funciona, y definitivamente puedes usarlo. (
.busca desde el directorio actual. Además de eso, es realmente una forma ligeramente diferente de escribir el comando en la muy buena respuesta de steeldriver ; puede usar el estilo que prefiera).También puede
findpasar varios nombres de archivogzipy ejecutarlo solo las veces que sea necesario, que casi siempre es solo una vez. Para hacer eso, use en+lugar de\;. El+argumento debería venir justo después{}.findreemplaza+con nombres de archivo adicionales, si los hay.Está bien usarlo
+incluso si solo hay unos pocos archivos coincidentes, y cuando hay muchos de ellos, puede ser notablemente más rápido que tener unagzipinvocación separada para cada archivo.Como menciona Steeldriver , puede usar en
-inamelugar de-namehacer coincidir archivos cuyo nombre termine como.csso.htmlpero con diferentes mayúsculas. Esto corresponde a habilitarnocasegloben elglobstarmétodo basado en lo descrito anteriormente.Finalmente, probablemente no tenga ningún archivo o directorio coincidente que comience con
.. Pero si lo hace,findlos incluye automáticamente. Si desea excluirlos (como sucede con elglobstarmétodo basado en detalles detallado anteriormente cuandodotglobestá desactivado), puede :La
globstarforma basada en lo descrito anteriormente es más simple de escribir, especialmente si excluye directorios y archivos que comienzan., ya que ese es el valor predeterminado.Que no hacer ...
Los nombres de archivo pueden contener cualquier carácter, excepto el separador de ruta
/y el carácter nulo . Existen muchas técnicas que se rompen en nombres de archivo extraños, y generalmente son más complicadas que las técnicas que siempre funcionan. Por lo tanto, sugiero evitarlos incluso cuando sepa (o piense que sabe) que están bien en su situación específica. Y, por supuesto, no debe usarlos si puede tener nombres de archivo con caracteres que pueden tratarse especialmente, incluidos los espacios.Es posible canalizar de forma segura la salida de
findotro comando que lo procesa si usa-print0o una acción similar para hacer que coloque un carácter nulo entre las rutas en lugar de una nueva línea , y no de otra manera. Los nombres de archivo pueden contener nuevas líneas (aunque te desaliento de nombrar deliberadamente archivos con ellos). Unfindcomando con la-printacción, incluidos los comandos de búsqueda sin acción explícita, ya que-printes el valor predeterminado, no produce resultados que se puedan canalizar de forma segura o de otro modo a otro comando que realice una acción en los archivos.La salida que se
findproduce con la-print0acción se puede canalizar de forma seguraxargs -0(el-0indicador indica quexargsdebe esperar una entrada separada por nulos).fuente
Para comprimir todos los archivos en una carpeta / subcarpeta de forma recursiva:
Descomprimir:
fuente
``sintaxis, pero el problema se aplica completamente cuando se usa también la$()sintaxis.)