Wie erhalte ich den Befehl find, um die Dateigröße mit dem Dateinamen auszudrucken?

105

Wenn ich den Befehl find wie folgt ausgebe:

$ find . -name *.ear

Es druckt aus:

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

Was ich in der Befehlszeile "drucken" möchte, ist der Name und die Größe:

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

Antworten:

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

nur das h extra aus der Antwort von jer.drab.org. spart mental Zeit bei der Umstellung auf MB;)

Shyam
quelle
8
Diese Version führt den "ls" -Prozess für jede Datei aus. Wenn Sie viele Dateien haben (z. B. über tausend), optimieren Sie diese besser entweder durch: find . -name '*.ear' -exec ls -lh {} + \;(GNU-Erweiterung) oder find . -name '*.ear' -print0 | xargs -0 ls -lh. Sie können auch hinzufügen, -type fwenn Sie nur an Dateien interessiert sind (oder -dzu ls hinzufügen , wenn Sie möchten, dass Verzeichnisse selbst ohne deren Inhalt aufgenommen werden).
ash108
2
Ihre Antwort schließt Verzeichnisse nicht aus, sodass Sie am Ende auch ls in Verzeichnissen ausführen, was eindeutig nicht das Richtige ist.
Faheem Mitha
2
Dies ist eine wirklich ineffiziente Vorgehensweise - und leider sind die Kommentare von ash108 auch nicht ideal. Es ist viel besser, die Option -printf zu verwenden, um zu finden.
oskarpearson
Die Antwort von dmazzoni ist viel effizienter, da bei jeder Datei ein Fork + Exec vermieden wird (100x schneller auf meinem Computer). Ich musste% k in% s ändern. @FaheemMitha: Sie können Optionen hinzufügen, -type fum nur reguläre Dateien zu zählen.
Herr Fooz
@FaheemMitha einfache Lösung ist find . -name "*.ear" -type ffür Dateien. -type dfunktioniert für Verzeichnisse.
anon58192932
111

Sie müssen -exec oder -printf verwenden. Printf funktioniert folgendermaßen:

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

-exec ist leistungsfähiger und ermöglicht die Ausführung beliebiger Befehle. Sie können also eine Version von 'ls' oder 'wc' verwenden, um den Dateinamen zusammen mit anderen Informationen auszudrucken. 'man find' zeigt Ihnen die verfügbaren Argumente für printf, die viel mehr als nur Dateigröße können.

[edit] -printf ist nicht im offiziellen POSIX-Standard enthalten. Überprüfen Sie daher, ob es von Ihrer Version unterstützt wird. Die meisten modernen Systeme verwenden jedoch GNU find oder eine ähnlich erweiterte Version, sodass eine gute Chance besteht, dass sie implementiert werden.

Leigh Caldwell
quelle
Es sieht so aus, als ob Ihr Beispiel genauer ist, aber ich kann das Beispiel anscheinend nicht für Solaris 10 verwenden.
Brian
Ich fürchte, Solaris find unterstützt -printf überhaupt nicht: jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/ find.1.html Sie könnten GNU find installieren, wenn Sie gestört werden könnten, andernfalls müssen Sie exec oder | verwenden wie von anderen vorgeschlagen.
Leigh Caldwell
1
+1 Das scheint sauberer zu sein. Um die Ausgabe zu formatieren, würde ich den columnBefehl add bevorzugen . find . -name *.ear -printf "%p %k KB\n" | column -t
Amol
1
Diese Antwort ist viel korrekter als die akzeptierte Antwort
bedrohlich
2
Die -printfOption funktioniert auch unter OS X nicht. Siehe stackoverflow.com/questions/752818/… .
Abeboparebop
33

Eine einfache Lösung besteht darin, die Option -ls in find zu verwenden:

find . -name \*.ear -ls

Das gibt Ihnen jeden Eintrag im normalen "ls-l" -Format. Oder, um die spezifische Ausgabe zu erhalten, nach der Sie zu suchen scheinen:

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

Dadurch erhalten Sie den Dateinamen, gefolgt von der Größe in KB.

Michael Cramer
quelle
Wusste noch nicht einmal von einer lsOption, diese sollte in der Liste der Antworten weit oben stehen als sie ist.
Prometheus
24

Mit gnu find denke ich, dass dies das ist, was Sie wollen. Es findet alle realen Dateien und keine Verzeichnisse (-typ f) und druckt für jede Datei den Dateinamen (% p), eine Registerkarte (\ t), die Größe in Kilobyte (% k), das Suffix "KB" und dann eine neue Zeile (\ n).

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

Wenn der Befehl printf die gewünschten Formatierungen nicht vornimmt, können Sie exec verwenden, gefolgt von dem Befehl, den Sie für jede Datei ausführen möchten. Verwenden Sie {} als Dateinamen und beenden Sie den Befehl mit einem Semikolon (;). Bei den meisten Shells sollten alle drei Charaktere mit einem Backslash versehen werden.

Hier ist eine einfache Lösung, die sie mit "ls -lh" findet und ausdruckt. Dabei wird die Größe in lesbarer Form angezeigt (k für Kilobyte, M für Megabyte):

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

Als weitere Alternative gibt "wc -c" die Anzahl der Zeichen (Bytes) in der Datei aus:

find . -type f -exec wc -c \{\} \;
dmazzoni
quelle
+1 Abgesehen davon, dass dies -name '*.ear'in den Beispielen weggelassen wurde, sollte dies die Antwort Nr. 1 sein. Es beantwortet die Frage genau, erklärt die Bedeutung der Syntax und bietet mehrere Alternativen.
OsakaWebbie
Dies sollte als Antwort akzeptiert werden, da nicht für jede Zeile ein neuer Befehl ausgeführt wird.
Daher
In der Tat sollte dies die richtige Antwort sein. Wenn Sie find . -type f -printf '%k KB\t %p\n'also zuerst die Dateigröße drucken, ist dies aufgrund der Ausrichtung höchstwahrscheinlich eine bessere Ausgabe in Bezug auf die Formatierung.
Myradio
8
find . -name '*.ear' -exec du -h {} \;

Dadurch erhalten Sie nur die Dateigröße anstelle aller unnötigen Inhalte.

Benutzer2121791
quelle
wcfunktioniert dafür einfach besser, wenn man die größe in bytes braucht.
Alex
4

Awk kann die Ausgabe korrigieren, um genau das zu geben, wonach der Fragesteller gefragt hat. Auf meinem Solaris 10-System gibt find -ls die Größe in KB als zweites Feld aus.

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

Verwenden Sie andernfalls -exec ls -lh und wählen Sie das Größenfeld aus der Ausgabe aus. Wieder unter 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
quelle
4

Warum nicht du -a benutzen ? Z.B

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

Funktioniert auf einem Mac

sietschie
quelle
3

Ich hatte unter Mac OS X Probleme damit, wo der Befehl find nicht unterstützt wird -printf.

Eine Lösung, die ich gefunden habe und die sich zugegebenermaßen auf die "Gruppe" für alle Dateien stützt, die "Mitarbeiter" sind, war ...

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

Dies teilt die lange Ausgabe in drei Token auf

  1. das Zeug vor dem Text "Mitarbeiter"
  2. die Dateigröße
  3. der Dateiname

Und dann werden die Token 2 und 3 ausgegeben, dh die Ausgabe ist die Anzahl der Bytes und dann der Dateiname

8071 sections.php
54681 services.php
37961 style.css
13260 thumb.php
70951 workshops.php
Mike M.
quelle
1
Nützlich zu wissen .. Die GNU-Version von findist über Homebrew mitbrew install findutils
mwfearnley
2

Dies sollte Ihnen das bieten, wonach Sie suchen, einschließlich Formatierung (dh Dateiname zuerst und Größe danach):

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

Beispielausgabe (wo ich früher -iname "*.php"ein Ergebnis erhalten habe):

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

Sie könnten dies versuchen:

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

Dies gibt Ihnen die Größe in Bytes. Der Befehl du akzeptiert jedoch auch die Parameter -k für KB und -m für MB. Es wird Ihnen eine Ausgabe wie geben

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

Scripter World Referenz

Scripter
quelle
1

Versuchen Sie die folgenden Befehle:

GNU stat:

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

BSD stat:

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

jedoch statist nicht Standard, so duoder wckönnte ein besserer Ansatz sein:

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

Wenn Sie die Gesamtgröße benötigen, finden Sie hier einen Skriptvorschlag

#!/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.
quelle