Come ottengo il comando find per stampare la dimensione del file con il nome del file?


106

Se emetto il comando find come segue:

$ find . -name *.ear

Stampa:

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

Quello che voglio 'stampare' sulla riga di comando è il nome e la dimensione:

./dir1/dir2/earFile1.ear  5000 KB
./dir1/dir2/earFile2.ear  5400 KB
./dir1/dir3/earFile1.ear  5400 KB

Risposte:


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

solo il h extra dalla risposta di jer.drab.org. fa risparmiare tempo nella conversione in MB mentalmente;)


8
Questa versione eseguirà il processo "ls" per ogni file. Se hai molti file (diciamo più di un migliaio) è meglio ottimizzarli con: find . -name '*.ear' -exec ls -lh {} + \;(estensione GNU) o find . -name '*.ear' -print0 | xargs -0 ls -lh. Inoltre potresti voler aggiungere -type fse sei interessato solo ai file (o aggiungere -da ls se vuoi che le directory stesse siano incluse senza il loro contenuto).
ash108

2
La tua risposta non esclude le directory, quindi finirai per eseguire ls anche sulle directory, il che chiaramente non è la cosa giusta da fare.
Faheem Mitha

2
Questo è un modo davvero inefficiente di fare le cose - e sfortunatamente anche i commenti di ash108 non sono ideali. È molto meglio usare l'opzione -printf per trovare.
oskarpearson

La risposta di dmazzoni è molto più efficiente perché evita un fork + exec su ogni file (100 volte più veloce sulla mia macchina). Ho dovuto cambiare% k in% s. @FaheemMitha: puoi aggiungere opzioni come -type fcontare solo i file normali.
Mr Fooz,

@FaheemMitha soluzione facile è find . -name "*.ear" -type fper i file. -type dfunziona per le directory.
anon58192932

111

È necessario utilizzare -exec o -printf. Printf funziona in questo modo:

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

-exec è più potente e consente di eseguire comandi arbitrari, quindi è possibile utilizzare una versione di "ls" o "wc" per stampare il nome del file insieme ad altre informazioni. 'man find' ti mostrerà gli argomenti disponibili per printf, che può fare molto di più della semplice dimensione del file.

[modifica] -printf non è nello standard POSIX ufficiale, quindi controlla se è supportato sulla tua versione. Tuttavia, la maggior parte dei sistemi moderni utilizzerà GNU find o una versione estesa in modo simile, quindi ci sono buone probabilità che venga implementata.


Sembra che il tuo esempio sia più preciso, ma non riesco a far funzionare l'esempio su Solaris 10.
Brian

Temo che Solaris find non supporti affatto -printf : jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/ find.1.html Potresti installare GNU find se puoi essere disturbato, altrimenti devi usare exec o | come suggerito da altri.
Leigh Caldwell,

1
+1 Sembra più pulito. Per formattare l'output preferirei aggiungere il columncomando. find . -name *.ear -printf "%p %k KB\n" | column -t
Amol

1
Questa risposta è un modo molto più corretto per farlo rispetto alla risposta accettata
minacciosamente il

2
L' -printfopzione non funziona neanche in OS X. Vedi stackoverflow.com/questions/752818/… .
abeboparebop

33

una soluzione semplice è usare l'opzione -ls in find:

find . -name \*.ear -ls

Questo ti dà ogni voce nel normale formato "ls -l". Oppure, per ottenere l'output specifico che sembri cercare, questo:

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

Che ti darà il nome del file seguito dalla dimensione in KB.


Non sapevo nemmeno lsun'opzione, questa dovrebbe essere molto più in alto nell'elenco delle risposte di quanto non sia.
Prometeo il

24

Usando gnu find, penso che questo sia quello che vuoi. Trova tutti i file reali e non le directory (-type f), e per ognuno stampa il nome del file (% p), una tabulazione (\ t), la dimensione in kilobyte (% k), il suffisso "KB" e poi una nuova riga (\ n).

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

Se il comando printf non formatta le cose nel modo desiderato, puoi usare exec, seguito dal comando che vuoi eseguire su ogni file. Usa {} per il nome del file e termina il comando con un punto e virgola (;). Sulla maggior parte delle shell, tutti e tre questi caratteri dovrebbero essere sottoposti a escape con una barra rovesciata.

Ecco una semplice soluzione che li trova e li stampa usando "ls -lh", che ti mostrerà la dimensione in forma leggibile dall'uomo (k per kilobyte, M per megabyte):

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

Come ancora un'altra alternativa, "wc -c" stamperà il numero di caratteri (byte) nel file:

find . -type f -exec wc -c \{\} \;

+1 Ad eccezione di aver omesso -name '*.ear'negli esempi, questa dovrebbe essere la risposta n. 1. Risponde con precisione alla domanda, spiega il significato della sintassi e offre più alternative.
OsakaWebbie

questa dovrebbe essere una risposta accettata in quanto non esegue un nuovo comando per ogni riga, quindi è molto più veloce di quello attualmente accettato da shyam
jirislav

In effetti questa dovrebbe essere la risposta giusta. Inoltre, ad find . -type f -printf '%k KB\t %p\n'esempio, stampare prima la dimensione del file, molto probabilmente sarà un risultato migliore in termini di formattazione a causa dell'allineamento.
myradio

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

Questo ti dà solo la dimensione del file, invece di tutte le cose non necessarie.


wcfunziona per questo solo meglio, se hai bisogno della dimensione in byte.
Alex

4

Awk può correggere l'output per fornire esattamente ciò che l'interrogante ha chiesto. Sul mio sistema Solaris 10, trova -ls stampa la dimensione in KB come secondo campo, quindi:

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

Altrimenti, usa -exec ls -lh e scegli il campo delle dimensioni dall'output. Di nuovo su 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

4

Perché non usare du -a ? Per esempio

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

Funziona su un Mac


3

Ho lottato con questo su Mac OS X dove il comando find non supporta -printf.

Una soluzione che ho trovato, che certamente si basa sul "gruppo" per tutti i file che sono "staff" è stata ...

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

Questo divide l'output lungo di ls in tre token

  1. le cose prima del testo "staff"
  2. la dimensione del file
  3. il nome del file

E poi restituisce i token 2 e 3, ovvero l'output è il numero di byte e quindi il nome del file

8071 sections.php
54681 services.php
37961 style.css
13260 thumb.php
70951 workshops.php

1
Utile da sapere .. La versione GNU di findè disponibile tramite homebrew conbrew install findutils
mwfearnley

2

Questo dovrebbe darti quello che stai cercando, inclusa la formattazione (cioè il nome del file prima e la dimensione dopo):

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

output di esempio (dove ho usato -iname "*.php"per ottenere qualche risultato):

./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

1

Potresti provare questo:

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

Questo ti darà la dimensione in byte. Ma il comando du accetta anche i parametri -k per KB e -m per MB. Ti darà un output come

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



1

Prova i seguenti comandi:

GNU stat:

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

BSD stat:

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

tuttavia statnon è standard, quindi duo wcpotrebbe essere un approccio migliore:

find . -type f -name *.ear -exec sh -c 'echo "{} $(wc -c < {})"' ';'


0

Se hai bisogno di ottenere la dimensione totale, ecco una proposta di script

#!/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"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.