Comment obtenir la commande find pour imprimer la taille du fichier avec le nom du fichier?

106

Si j'émets la commande find comme suit:

$ find . -name *.ear

Il imprime:

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

Ce que je veux `` imprimer '' sur la ligne de commande, c'est le nom et la taille:

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

Réponses:

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

juste le h supplémentaire de la réponse de jer.drab.org. économise du temps en convertissant mentalement en Mo;)

timide
la source
8
Cette version exécutera le processus "ls" pour chaque fichier. Si vous avez beaucoup de fichiers (disons plus d'un millier), il vaut mieux optimiser cela soit par: find . -name '*.ear' -exec ls -lh {} + \;(extension GNU) ou find . -name '*.ear' -print0 | xargs -0 ls -lh. Vous pouvez également ajouter -type fsi vous n'êtes intéressé que par les fichiers (ou ajouter -dà ls si vous voulez que les répertoires eux-mêmes soient inclus sans leur contenu).
ash108
2
Votre réponse n'exclut pas les répertoires, vous finirez donc par exécuter également ls sur les répertoires, ce qui n'est clairement pas la bonne chose à faire.
Faheem Mitha
2
C'est une façon vraiment inefficace de faire les choses - et malheureusement les commentaires d'ash108 ne sont pas non plus idéaux. Il est préférable d'utiliser l'option -printf pour trouver.
oskarpearson
La réponse de dmazzoni est beaucoup plus efficace car elle évite un fork + exec sur chaque fichier (100x plus rapide sur ma machine). J'ai dû changer% k en% s. @FaheemMitha: vous pouvez ajouter des options comme -type fne compter que les fichiers normaux.
Mr Fooz le
@FaheemMitha solution facile est find . -name "*.ear" -type fpour les fichiers. -type dfonctionne pour les répertoires.
anon58192932
111

Vous devez utiliser -exec ou -printf. Printf fonctionne comme ceci:

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

-exec est plus puissant et vous permet d'exécuter des commandes arbitraires - vous pouvez donc utiliser une version de «ls» ou «wc» pour afficher le nom du fichier avec d'autres informations. «man find» vous montrera les arguments disponibles pour printf, qui peut faire beaucoup plus que simplement la taille du fichier.

[edit] -printf n'est pas dans le standard POSIX officiel, vérifiez donc s'il est pris en charge sur votre version. Cependant, la plupart des systèmes modernes utiliseront GNU find ou une version étendue similaire, il y a donc de bonnes chances qu'elle soit implémentée.

Leigh Caldwell
la source
Il semble que votre exemple soit plus précis, mais je n'arrive pas à faire fonctionner l'exemple sur Solaris 10.
Brian
Je crains que Solaris ne prenne en charge -printf du tout: jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/ find.1.html Vous pouvez installer GNU find si vous pouvez être dérangé, sinon vous devez utiliser exec ou | comme suggéré par d'autres.
Leigh Caldwell
1
+1 Cela semble plus propre. Pour formater la sortie, je préférerais ajouter une columncommande. find . -name *.ear -printf "%p %k KB\n" | column -t
Amol
1
Cette réponse est une façon beaucoup plus correcte de le faire que la réponse acceptée
menaçante
2
L' -printfoption ne fonctionne pas non plus sous OS X. Voir stackoverflow.com/questions/752818/… .
abeboparebop
33

une solution simple consiste à utiliser l'option -ls dans find:

find . -name \*.ear -ls

Cela vous donne chaque entrée au format normal "ls -l". Ou, pour obtenir la sortie spécifique que vous semblez rechercher, ceci:

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

Ce qui vous donnera le nom du fichier suivi de la taille en Ko.

Michael Cramer
la source
Je ne connaissais même pas une lsoption, cela devrait être beaucoup plus haut dans la liste des réponses qu'elle ne l'est.
Prometheus le
24

En utilisant gnu find, je pense que c'est ce que vous voulez. Il trouve tous les fichiers réels et non les répertoires (-type f), et pour chacun imprime le nom de fichier (% p), une tabulation (\ t), la taille en kilo-octets (% k), le suffixe "Ko", puis une nouvelle ligne (\ n).

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

Si la commande printf ne formate pas les choses comme vous le souhaitez, vous pouvez utiliser exec, suivi de la commande que vous souhaitez exécuter sur chaque fichier. Utilisez {} pour le nom de fichier et terminez la commande par un point-virgule (;). Sur la plupart des shells, ces trois caractères doivent être échappés avec une barre oblique inverse.

Voici une solution simple qui les trouve et les affiche en utilisant "ls -lh", qui vous montrera la taille sous une forme lisible par l'homme (k pour kilo-octets, M pour mégaoctets):

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

Comme autre alternative, "wc -c" affichera le nombre de caractères (octets) dans le fichier:

find . -type f -exec wc -c \{\} \;
dmazzoni
la source
+1 Sauf pour avoir omis -name '*.ear'dans les exemples, cela devrait être la réponse n ° 1. Il répond précisément à la question, explique le sens de la syntaxe et propose de multiples alternatives.
OsakaWebbie
cela devrait être une réponse acceptée car elle n'exécute pas de nouvelle commande pour chaque ligne, donc elle est beaucoup plus rapide que celle actuellement acceptée de shyam
jirislav
En effet, cela devrait être la bonne réponse. De plus, find . -type f -printf '%k KB\t %p\n'c'est -à- dire que l'impression de la taille du fichier en premier sera probablement une meilleure sortie en termes de formatage en raison de l'alignement.
myradio
8
find . -name '*.ear' -exec du -h {} \;

Cela vous donne uniquement la taille du fichier, au lieu de toutes les choses inutiles.

user2121791
la source
wcfonctionne juste mieux pour cela, si vous avez besoin de la taille en octets.
Alex
4

Awk peut réparer la sortie pour donner exactement ce que l'interrogateur a demandé. Sur mon système Solaris 10, find -ls imprime la taille en Ko comme deuxième champ, donc:

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

Sinon, utilisez -exec ls -lh et sélectionnez le champ de taille dans la sortie. Encore une fois sur 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
tpgould
la source
4

Pourquoi ne pas utiliser du -a ? Par exemple

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

Fonctionne sur un Mac

sietschie
la source
3

J'ai eu du mal avec cela sur Mac OS X où la commande find ne prend pas en charge -printf.

Une solution que j'ai trouvée, qui repose certes sur le `` groupe '' pour tous les fichiers étant `` personnel '' était ...

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

Cela divise la sortie longue de ls en trois jetons

  1. le truc avant le texte 'staff'
  2. la taille du fichier
  3. le nom du fichier

Et puis renvoie les jetons 2 et 3, c'est-à-dire que la sortie est le nombre d'octets, puis le nom de fichier

8071 sections.php
54681 services.php
37961 style.css
13260 thumb.php
70951 workshops.php
Mike M
la source
1
Utile à savoir .. La version GNU de findest disponible via homebrew avecbrew install findutils
mwfearnley
2

Cela devrait vous donner ce que vous recherchez, formatage inclus (c'est-à-dire le nom du fichier en premier et la taille après):

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

exemple de sortie (où j'avais l'habitude -iname "*.php"d'obtenir un résultat):

./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
la source
1

Vous pouvez essayer ceci:

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

Cela vous donnera la taille en octets. Mais la commande du accepte également les paramètres -k pour KB et -m pour MB. Cela vous donnera une sortie comme

5000  ./dir1/dir2/earFile1.ear
5400  ./dir1/dir2/earFile2.ear
5400  ./dir1/dir3/earFile1.ear
Yaba
la source
1
find . -name "*.ear" | xargs ls -sh
killdash10
la source
1
$ trouver. -nom "test *" -exec du -sh {} \;
4,0K ./test1
0 ./test2
0 ./test3
0 ./test4
$

Référence Scripter World

scripteur
la source
1

Essayez les commandes suivantes:

GNU stat:

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

BSD stat:

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

cependant statn'est pas standard, donc duou wcpourrait être une meilleure approche:

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

Si vous avez besoin d'obtenir la taille totale, voici une proposition de 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"
Damien C
la source