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
-r
Funciona 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
-r
opción no funciona,-k
y-f
está funcionando, puedo usarlos así: para i infind | grep -E "\.css$|\.html$"
; do gzip -vkf "$ i"; hecho``...`
proporciona una cadena, no una lista.for
usa 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 new
ygzip style.css
se ejecutarán.export IFS=$'\n'
justo antes delfor
ciclo.yo usaría
Cambie
name
ainame
si desea hacer coincidir las extensiones entre mayúsculas y minúsculas (es decir, incluir.CSS
y / o.HTML
extensiones). Puede omitir el/path/to/dir
si desea iniciar la búsqueda recursiva desde el directorio actual.fuente
--keep
cambio, 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
tar
la lista de archivos como salidafind
, en lugar de los archivos en sí mismos?-T
opcióntar
procesa la entrada como nombres de archivo.Solía respuesta de steeldriver , pero me gusta para terminar con el
--best
y--force
opciones.cd
en cualquier carpeta y escriba este código. Todos sus archivos coincidentes serán comprimidos.--best
para obtener la mejor relación de compresión.--force
para sobrescribir sin preguntar si ya hay un archivo comprimido.fuente
Puedes usar globstar.
Con la
globstar
opción de shell habilitada, todo lo que necesita esgzip -vk **/*.{css,html}
.El shell Bash tiene una
globstar
opción que te permite escribir globos recursivos con**
.shopt -s globstar
lo habilita Pero es posible que no desee hacer eso para otros comandos que ejecute más tarde, por lo que puede ejecutarlo junto con sugzip
comando en una subshell .Este comando
gzip
es todo.css
y.html
los 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
nocaseglob
opció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 habilitarglobstar
continuación, puede ejecutarshopt -s globstar
; entonces puedes ejecutar el comando:Puede deshabilitar
globstar
conshopt -u globstar
. Puede verificar si está habilitado actualmente conshopt globstar
.Cómo funciona
La clave de cómo funciona este
gzip
comando 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 (.css
o.html
en 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 ladotglob
opció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).
gzip
no será llamado en absoluto, por lo que no obtendrá un trabajo a medio hacer.Si ocurre este error, o si le preocupa, puede usarlo
find
con-exec
, como lo describe steeldriver (con{} \;
) o como lo describo a continuación (con{} +
).Se puede usar
find
con la-exec
acción y+
para la eficiencia.El
gzip
comando admite recibir nombres de varios archivos para comprimir. Pero estefind
comando, aunque funciona bien y no será lento a menos que tenga muchos archivos, ejecuta elgzip
comando 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
find
pasar varios nombres de archivogzip
y 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{}
.find
reemplaza+
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 unagzip
invocación separada para cada archivo.Como menciona Steeldriver , puede usar en
-iname
lugar de-name
hacer coincidir archivos cuyo nombre termine como.css
o.html
pero con diferentes mayúsculas. Esto corresponde a habilitarnocaseglob
en elglobstar
método basado en lo descrito anteriormente.Finalmente, probablemente no tenga ningún archivo o directorio coincidente que comience con
.
. Pero si lo hace,find
los incluye automáticamente. Si desea excluirlos (como sucede con elglobstar
método basado en detalles detallado anteriormente cuandodotglob
está desactivado), puede :La
globstar
forma 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
find
otro comando que lo procesa si usa-print0
o 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). Unfind
comando con la-print
acción, incluidos los comandos de búsqueda sin acción explícita, ya que-print
es 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
find
produce con la-print0
acción se puede canalizar de forma seguraxargs -0
(el-0
indicador indica quexargs
debe 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.)