Encuentre todos los archivos de cero bytes en directorios y subdirectorios

82

¿Cómo puedo encontrar todos los archivos de cero bytes en un directorio y sus subdirectorios?

He hecho esto:

#!/bin/bash
lns=`vdir -R *.* $dir| awk '{print $8"\t"$5}'`
temp=""
for file in $lns; do
    if test $file = "0"; then
        printf $temp"\t"$file"\n"
    fi
    temp=$file
done

Pero, solo obtengo resultados en el directorio actual, no en los subdirectorios, y si algún nombre de archivo contiene un espacio, solo obtengo la primera palabra seguida de la pestaña

Civa
fuente
1
Puede que le guste leer man find.
Alk
1
Pregunta también publicada en Unix y Linux : no publique la misma pregunta en varios lugares.
Glenn Jackman
La próxima vez que no repita esto debido a un problema en mi navegador con stackoverflow publiqué en superusuario, pero ahora el problema se solucionó borrando las cookies del historial y capturando, es decir, volví a preguntar aquí
Civa

Respuestas:

174

Para imprimir los nombres de todos los archivos en y por debajo de $ dir de tamaño 0:

find "$dir" -size 0

Tenga en cuenta que no todas las implementaciones de findproducirán resultados de forma predeterminada, por lo que es posible que deba hacer lo siguiente:

find "$dir" -size 0 -print

Dos comentarios sobre el ciclo final de la pregunta:

En lugar de iterar sobre cada otra palabra en una cadena y ver si los valores alternativos son cero, puede eliminar parcialmente el problema que está teniendo con los espacios en blanco iterando sobre las líneas. p.ej:

printf '1 f1\n0 f 2\n10 f3\n' | while read size path; do
    test "$size" -eq 0 && echo "$path"; done

Tenga en cuenta que esto fallará en su caso si alguna de las rutas generadas por ls contiene nuevas líneas, y esto refuerza 2 puntos: no analice lsy tenga una política de nombres sensata que no permita espacios en blanco en las rutas.

En segundo lugar, para generar los datos del bucle, no es necesario almacenar la salida en una variable solo para echoél. Si simplemente deja que el bucle escriba su salida en stdout, logra lo mismo, pero evita almacenarlo.

William Pursell
fuente
¿Puedo filtrar un directorio que no sea * .xml
Civa
2
También hay una -emptyopción conveniente .
Wesley Baugh
@WesleyBaugh con la opción -empty también obtiene directorios con cero archivos adentro
Igor Scabini
1
@IgorScabini Si desea limitar los archivos, puede hacerlo con -type f.
Wesley Baugh
¡Encantador! Simple y al grano. Hombre, no uso este findcomando lo suficiente. Realmente tengo que superar mi miedo a descubrirlo. Tan útil.
racl101
32

Como complemento a las respuestas anteriores:

Si desea eliminar esos archivos

find $dir -size 0 -type f -delete
LinuxLuigi
fuente
1
no es necesario borrar todo el archivo de tamaño 0 todo el tiempo.
Raghvendra
luego, cómo eliminar un archivo dentro de una carpeta con tamaño 0
Raghvendra
-exec /bin/rm {} \;o -exec /bin/rm {} +también funcionará en findimplementaciones que no sean de GNU , que no admiten la extensión no estándar-delete
Gert van den Berg
8

No, no tienes que molestarte en grep.

find $dir -size 0 ! -name "*.xml"
Dosificador
fuente
3

Bash 4+ probado: esta es la forma correcta de buscar el tamaño 0:

find /path/to/dir -size 0 -type f -name "*.xml"

Busque varias extensiones de archivo de tamaño 0:

find /path/to/dir -size 0 -type f \( -iname \*.css -o -iname \*.js \)

Nota: Si eliminó \ (... \), los resultados serían todos los archivos que cumplen con este requisito, por lo que se ignora el tamaño 0.

Mike Q
fuente
-inameno es portátil para algunas implementaciones que no son de GNU. findVea aquí una lista de opciones estándar
Gert van den Berg