Warum erhalte ich 4 Aufrufe anstelle von 3, wenn ich dieses find -execdir {} + (plus) verwende?

8

Ich habe hier gelesen , dass Sie die Anzahl der Aufrufe von commandin zählen können, -exec command {} +indem Sie | wc -lbis zum Ende weiterleiten.

Ich verstehe zwar, dass dies -execdiranders ist, aber für jedes übereinstimmende Unterverzeichnis, das findentdeckt wird, wird ein Aufruf des commandUnterverzeichnisses ausgeführt, in dem es enthalten ist, wenn ich mehr als eine Datei habe, die in einem Unterverzeichnis übereinstimmt, sollte dies nicht der Fall sein Bekomme ich nicht die Anzahl der Aufrufe, die der Anzahl der übereinstimmenden Unterverzeichnisse entspricht, und nicht die Anzahl der Aufrufe, die der Anzahl der übereinstimmenden Dateien in diesen Unterverzeichnissen entsprechen?

Ich werde mit letzterem enden, wenn ich Folgendes ausführe:

$ find . -name "bob*" -execdir echo {} + | wc -l

Die Manpage für die execdir command {} +Staaten, dass die erstere der Fall sein sollte:

Wie bei der -execAktion erstellt die +Form von -execdireine Befehlszeile, um mehr als eine übereinstimmende Datei zu verarbeiten, aber bei jedem Aufruf von commandwerden nur Dateien aufgelistet, die im selben Unterverzeichnis vorhanden sind.


dh

Ich erhalte:

./file1inDir1
./file2inDir1
./file3InDir2
./file4InDir3

Wenn ich das erwarte, basierend auf der Manpage:

./file1inDir1 ./file2inDir1
./file3InDir2
./file4InDir3
leeand00
quelle
Auf diese Weise können Sie Befehlsaufrufe im Allgemeinen nicht zählen. Wenn der Befehl lautet echound die Argumente von generiert werden {} +und Sie keine Zeilenumbrüche in Ihren Dateinamen haben (die meisten Leute nicht), dann ist die Anzahl der Zeilen die Anzahl der Aufrufe und es funktioniert. Wenn Befehl gesagt wird head -n 999000 /dev/urandom, geht es schrecklich schief.
Dave_thompson_085

Antworten:

11

Dies ist ein Leistungsproblem von find . In findutilsVersion 4.3.4, eine Abhilfe hatte die Anzahl der Argumente zu beschränken, -execdir ... {} +verwenden zu 1. In der Version 4.5.9 die Grenze entfernt wurde.

Siehe ein Beispiel:

$ mkdir -p dir{1..3}
$ touch dir{1..3}/file1 dir2/file{1..3}
$ find
.
./dir1
./dir1/file1
./dir2
./dir2/file1
./dir2/file2
./dir2/file3
./dir3
./dir3/file1

Mit -execdir {} +sollte der Befehl dreimal ausgeführt werden. Der zweite Aufruf sollte 3 Argumente haben.

Mit find 4.4.2:

$ find-4.4.2 . -name "file*" -execdir sh -c 'echo "Executing $@ in $(pwd)"' find-sh {} +
Executing ./file1 in /path/to/dir1
Executing ./file1 in /path/to/dir2
Executing ./file2 in /path/to/dir2
Executing ./file3 in /path/to/dir2
Executing ./file1 in /path/to/dir3

Mit find4.6.0:

$ find-4.6.0 . -name "file*" -execdir sh -c 'echo "Executing $@ in $(pwd)"' find-sh {} +
Executing ./file1 in /path/to/dir1
Executing ./file1 ./file2 ./file3 in /path/to/dir2
Executing ./file1 in /path/to/dir3
Chaos
quelle