¿Cómo obtengo el comando de búsqueda para imprimir el tamaño del archivo con el nombre del archivo?

106

Si publico el comando de búsqueda de la siguiente manera:

$ find . -name *.ear

Imprime:

./dir1/dir2/earFile1.ear
./dir1/dir2/earFile2.ear
./dir1/dir3/earFile1.ear

Lo que quiero 'imprimir' en la línea de comando es el nombre y el tamaño:

./dir1/dir2/earFile1.ear  5000 KB
./dir1/dir2/earFile2.ear  5400 KB
./dir1/dir3/earFile1.ear  5400 KB
Brian Hart
fuente

Respuestas:

109
find . -name '*.ear' -exec ls -lh {} \;

solo el h extra de la respuesta de jer.drab.org. ahorra tiempo al convertir a MB mentalmente;)

shyam
fuente
8
Esta versión ejecutará el proceso "ls" para cada archivo. Si tiene muchos archivos (digamos, más de mil) es mejor optimizarlos con: find . -name '*.ear' -exec ls -lh {} + \;(extensión GNU) o find . -name '*.ear' -print0 | xargs -0 ls -lh. También es posible que desee agregar -type fsi solo está interesado en archivos (o agregar -da ls si desea que los directorios se incluyan sin su contenido).
ash108
2
Su respuesta no excluye directorios, por lo que terminará ejecutando ls en directorios también, lo que claramente no es lo correcto.
Faheem Mitha
2
Esta es una forma realmente ineficiente de hacer las cosas y, desafortunadamente, los comentarios de ash108 tampoco son ideales. Es mucho mejor usar la opción -printf para buscar.
oskarpearson
La respuesta de dmazzoni es mucho más eficiente porque evita un fork + exec en cada archivo (100 veces más rápido en mi máquina). Tuve que cambiar% k a% s. @FaheemMitha: puede agregar opciones como -type fsolo contar archivos regulares.
Mr Fooz
@FaheemMitha es una solución fácil find . -name "*.ear" -type fpara archivos. -type dfunciona para directorios.
anon58192932
111

Necesita utilizar -exec o -printf. Printf funciona así:

find . -name *.ear -printf "%p %k KB\n"

-exec es más poderoso y le permite ejecutar comandos arbitrarios, por lo que podría usar una versión de 'ls' o 'wc' para imprimir el nombre del archivo junto con otra información. 'man find' le mostrará los argumentos disponibles para printf, que pueden hacer mucho más que solo.

[editar] -printf no está en el estándar POSIX oficial, así que verifique si es compatible con su versión. Sin embargo, la mayoría de los sistemas modernos usarán GNU find o una versión similar extendida, por lo que es muy probable que se implemente.

Leigh Caldwell
fuente
Parece que su ejemplo es más preciso, pero parece que no puedo hacer que el ejemplo funcione en Solaris 10.
Brian
Me temo que Solaris find no admite -printf en absoluto: jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/ find.1.html Puede instalar GNU find si se le puede molestar, de lo contrario necesita usar exec o | como lo sugirieron otros.
Leigh Caldwell
1
+1 Esto parece más limpio. Para formatear la salida, preferiría agregar el columncomando. find . -name *.ear -printf "%p %k KB\n" | column -t
Amol
1
Esta respuesta es una forma mucho más correcta de hacerlo que la respuesta aceptada
amenazadoramente
2
La -printfopción tampoco funciona en OS X. Consulte stackoverflow.com/questions/752818/… .
abeboparebop
33

una solución simple es usar la opción -ls en find:

find . -name \*.ear -ls

Eso le da cada entrada en el formato normal "ls -l". O, para obtener la salida específica que parece estar buscando, esto:

find . -name \*.ear -printf "%p\t%k KB\n"

Lo que le dará el nombre del archivo seguido del tamaño en KB.

Michael Cramer
fuente
Ni siquiera conocía una lsopción, esto debería estar mucho más arriba en la lista de respuestas de lo que es.
Prometeo
24

Usando gnu find, creo que esto es lo que quieres. Encuentra todos los archivos reales y no directorios (-tipo f), y para cada uno imprime el nombre del archivo (% p), una pestaña (\ t), el tamaño en kilobytes (% k), el sufijo "KB" y luego una nueva línea (\ n).

find . -type f -printf '%p\t%k KB\n'

Si el comando printf no formatea las cosas de la manera que desea, puede usar exec, seguido del comando que desea ejecutar en cada archivo. Use {} para el nombre del archivo y termine el comando con un punto y coma (;). En la mayoría de los proyectiles, los tres personajes deben escaparse con una barra invertida.

Aquí hay una solución simple que los encuentra e imprime usando "ls -lh", que le mostrará el tamaño en forma legible por humanos (k para kilobytes, M para megabytes):

find . -type f -exec ls -lh \{\} \;

Como otra alternativa más, "wc -c" imprimirá el número de caracteres (bytes) en el archivo:

find . -type f -exec wc -c \{\} \;
dmazzoni
fuente
+1 Excepto por haberlo omitido -name '*.ear'en los ejemplos, esta debería ser la respuesta n. ° 1. Responde a la pregunta con precisión, explica el significado de la sintaxis y ofrece múltiples alternativas.
OsakaWebbie
esta debe ser una respuesta aceptada ya que no ejecuta un nuevo comando para cada línea, por lo que es mucho más rápido que el actualmente aceptado de
shyam
De hecho, esta debería ser la respuesta correcta. Además, find . -type f -printf '%k KB\t %p\n'es decir, imprimir primero el tamaño del archivo, probablemente será un resultado más agradable en términos de formato debido a la alineación.
myradio
8
find . -name '*.ear' -exec du -h {} \;

Esto le brinda lo único, en lugar de todas las cosas innecesarias.

usuario2121791
fuente
wcfunciona para esto simplemente mejor, si necesita el tamaño en bytes.
Alex
4

Awk puede arreglar la salida para dar exactamente lo que pidió el interlocutor. En mi sistema Solaris 10, busque -ls imprime el tamaño en KB como segundo campo, así:

% find . -name '*.ear' -ls | awk '{print $2, $11}'
5400 ./dir1/dir2/earFile2.ear
5400 ./dir1/dir2/earFile3.ear
5400 ./dir1/dir2/earFile1.ear

De lo contrario, use -exec ls -lh y seleccione el campo de tamaño de la salida. De nuevo en Solaris 10:

% find . -name '*.ear' -exec ls -lh {} \; | awk '{print $5, $9}'
5.3M ./dir1/dir2/earFile2.ear
5.3M ./dir1/dir2/earFile3.ear
5.3M ./dir1/dir2/earFile1.ear
debería
fuente
4

¿Por qué no usar du -a ? P.ej

find . -name "*.ear" -exec du -a {} \;

Funciona en Mac

sietschie
fuente
3

Luché con esto en Mac OS X donde el comando de búsqueda no es compatible -printf.

Una solución que encontré, que ciertamente se basa en el 'grupo' para que todos los archivos sean 'personal' fue ...

ls -l -R | sed 's/\(.*\)staff *\([0-9]*\)..............\(.*\)/\2 \3/'

Esto divide la salida larga de ls en tres tokens

  1. las cosas antes del texto 'personal'
  2. el tamaño del archivo
  3. el nombre del archivo

Y luego genera los tokens 2 y 3, es decir, la salida es el número de bytes y luego el nombre del archivo

8071 sections.php
54681 services.php
37961 style.css
13260 thumb.php
70951 workshops.php
Mike M
fuente
1
Es útil saber ... La versión GNU de findestá disponible a través de homebrew conbrew install findutils
mwfearnley
2

Esto debería proporcionarle lo que está buscando, incluido el formato (es decir, el nombre del archivo primero y el tamaño después):

find . -type f -iname "*.ear" -exec du -ah {} \; | awk '{print $2"\t", $1}'

salida de muestra (donde solía -iname "*.php"obtener algún resultado):

./plugins/bat/class.bat.inc.php  20K
./plugins/quotas/class.quotas.inc.php    8.0K
./plugins/dmraid/class.dmraid.inc.php    8.0K
./plugins/updatenotifier/class.updatenotifier.inc.php    4.0K
./index.php      4.0K
./config.php     12K
./includes/mb/class.hwsensors.inc.php    8.0K
adriano72
fuente
1

Puedes probar esto:

find. -name *.ear -exec du {} \;

Esto le dará el tamaño en bytes. Pero el comando du también acepta los parámetros -k para KB y -m para MB. Te dará una salida como

5000  ./dir1/dir2/earFile1.ear
5400  ./dir1/dir2/earFile2.ear
5400  ./dir1/dir3/earFile1.ear
Yaba
fuente
1
find . -name "*.ear" | xargs ls -sh
killdash10
fuente
1

Pruebe los siguientes comandos:

GNU stat:

find . -type f -name *.ear -exec stat -c "%n %s" {} ';'

BSD stat:

find . -type f -name *.ear -exec stat -f "%N %z" {} ';'

Sin embargo stat, no es estándar, por lo que duo wcpodría ser un mejor enfoque:

find . -type f -name *.ear -exec sh -c 'echo "{} $(wc -c < {})"' ';'
Kenorb
fuente
0
find . -name "*.ear" -exec ls -l {} \;
Jeremy Weathers
fuente
0

Si necesita obtener el tamaño total, aquí hay una propuesta de guión

#!/bin/bash
totalSize=0

allSizes=`find . -type f -name *.ear -exec stat -c "%s" {} \;`

for fileSize in $allSizes; do
    totalSize=`echo "$(($totalSize+$fileSize))"`
done
echo "Total size is $totalSize bytes"
Damien C
fuente