test solo regulares regular probar letras expressions expresiones expresion example especiales espacios espacio ejemplos caracteres blanco alfanumerico regex linux bash sum diskspace

regex - solo - ¿Uso de disco de archivos cuyos nombres coinciden con una expresión regular, en Linux?



probar expresiones regulares (6)

Ejecute esto en un Bourne Shell para declarar una función que calcula la suma de tamaños de todos los archivos que coinciden con un patrón de expresiones regulares en el directorio actual:

sizeofregex() { IFS=$''/n''; for x in $(find . -regex "$1" 2> /dev/null); do du -sk "$x" | cut -f1; done | awk ''{s+=$1} END {print s}'' | sed ''s/^$/0/''; unset IFS; }

(Alternativamente, puedes ponerlo en un script).

Uso:

cd /where/to/look sizeofregex ''myregex''

El resultado será un número (en KiB), incluido 0 (si no hay archivos que coincidan con su expresión regular).

Si no desea que se vea en otros sistemas de archivos (supongamos que quiere buscar todos los archivos .so en / , que es un montaje de /dev/sda1 , pero no en /home , que es un montaje de /dev/sdb1 , agregue un parámetro -xdev para find en la función anterior.

Por lo tanto, en muchas situaciones quería una forma de saber qué cantidad de espacio de disco usaba cada cosa, así que sé de qué deshacerme, convertir a otro formato, almacenar en otro lugar (como DVD de datos), mover a otra partición, etc. En este caso estoy viendo una partición de Windows desde un dispositivo de arranque SliTaz Linux .

En la mayoría de los casos, lo que quiero es el tamaño de los archivos y las carpetas, y para eso uso ncdu basado en ncdu :

Pero en este caso, quiero obtener el tamaño de todos los archivos que coincidan con una expresión regular . Un ejemplo de expresiones regulares para archivos .bak:

.*/.bak$

¿Cómo obtengo esa información, considerando un Linux estándar con utilidades básicas de GNU o BusyBox ?

Editar: El resultado está destinado a ser analizable por un script.


La respuesta aceptada sugiere usar

find . -regex ''.*/.bak'' -print0 | du --files0-from=- -ch | tail -1

pero eso no funciona en mi sistema ya que du no conoce una --files-0-from en mi sistema. Solo GNU du conoce esa opción, no es parte del estándar POSIX (por lo que no la encontrará en FreeBSD o macOS), ni la encontrará en los sistemas Linux basados en BusyBox (por ejemplo, la mayoría de los sistemas Linux) o cualquier otro sistema Linux que no usa la versión GNU du .

Luego hay una respuesta que sugiere usar:

find path/to/directory -iregex .*/.bak$ -exec du -csh ''{}'' + | tail -1

Esta solución funcionará siempre que no se encuentren demasiados archivos, ya que + significa que find intentará invocar du con tantos hits como sea posible en una sola llamada, sin embargo, podría haber un número máximo de argumentos (N) a el sistema admite y si hay más visitas que este valor, find llamará du varias veces, dividiendo las visitas en grupos menores o iguales a N elementos cada una y en este caso el resultado será incorrecto y solo mostrará el tamaño de la última llamada du .

Finalmente, hay una respuesta usando stat y awk , que es una buena manera de hacerlo, pero depende del globbing del shell de una forma que solo admite Bash 4.xo posterior. No funcionará con versiones anteriores y si funciona con otras shells es impredecible.

Una solución de conformidad POSIX (funciona en Linux, macOS y cualquier variante BSD), que no sufre ninguna limitación y que seguramente funcionará con cada shell sería:

find . -regex ''.*/.bak'' -exec stat -f "%z" {} /; | awk ''{s += $1} END {print s}''


Las soluciones anteriores no funcionaron correctamente para mí (tuve problemas al conectar du ) pero las siguientes funcionaron muy bien:

find path/to/directory -iregex ".*/.bak$" -exec du -csh ''{}'' + | tail -1

La opción iregex es una expresión regular insensible a mayúsculas y minúsculas. Use regex si desea que sea sensible a mayúsculas y minúsculas.

Si no se siente cómodo con expresiones regulares, puede usar los iname o name (el anterior es insensible a mayúsculas y minúsculas):

find path/to/directory -iname "*.bak" -exec du -csh ''{}'' + | tail -1

En caso de que desee el tamaño de cada coincidencia (en lugar de solo el total combinado), simplemente omita el comando de la cola entintada:

find path/to/directory -iname "*.bak" -exec du -csh ''{}'' +

Estos enfoques evitan el problema del subdirectorio en la respuesta de @MaddHackers.

Espero que esto ayude a otros en la misma situación (en mi caso, encontrar el tamaño de todas las DLL en una solución .NET).


Si estás bien con glob-patterns y solo te interesa el directorio actual:

stat -c "%s" *.bak | awk ''{sum += $1} END {print sum}''

o

sum=0 while read size; do (( sum += size )); done < <(stat -c "%s" *.bak) echo $sum

La directiva %s para stat da bytes, no kilobytes.

Si desea descender a subdirectorios, con la versión 4 de bash, puede shopt -s globstar y usar el patrón **/*.bak


Sugiero algo como: find . -regex ''.*/.bak'' -print0 | du --files0-from=- -ch | tail -1 find . -regex ''.*/.bak'' -print0 | du --files0-from=- -ch | tail -1

Algunas notas:

  • La opción -print0 para find y --files0-from para du están ahí para evitar problemas con el espacio en blanco en los nombres de archivo
  • La expresión regular se ./dir1/subdir2/file.bak toda la ruta, por ejemplo ./dir1/subdir2/file.bak , no solo file.bak , por lo que si la modifica, tenga eso en cuenta
  • Usé h flag para du para producir un formato "legible para humanos", pero si quieres analizar el resultado, es posible que estés mejor con k (siempre usa kilobytes)
  • Si elimina el comando tail , verá adicionalmente los tamaños de archivos y directorios particulares

Sidenote: una buena herramienta de GUI para averiguar quién se comió tu espacio en disco es FileLight . No contiene expresiones regulares, pero es muy útil para encontrar directorios grandes o archivos que obstruyen el disco.


du es mi respuesta favorita Si tiene una estructura de sistema de archivos fija, puede usar:

du -hc *.bak

Si necesita agregar subdirectorios, simplemente agregue:

du -hc *.bak **/*.bak **/**/*.bak

etcétera etcétera

Sin embargo, este no es un comando muy útil, por lo tanto, usando su búsqueda:

TOTAL=0;for I in $(find . -name /*.bak); do TOTAL=$((TOTAL+$(du $I | awk ''{print $1}''))); done; echo $TOTAL

Eso hará eco del tamaño total en bytes de todos los archivos que encuentre.

Espero que ayude.