Wie verwende ich ein Rohr in dem exec Parameter für einen Befehl find?
Frage
Ich versuche, einen Befehl find zu konstruieren, eine Reihe von Dateien in einem Verzeichnis zu verarbeiten. Leider -exec
auf Entdeckung erlaubt es nicht, Rohr zu verwenden oder sogar \|
weil die Shell zuerst das Zeichen interpretiert.
Hier ist speziell, was ich versuche zu tun (was nicht funktioniert, weil Rohr den Befehl find endet):
find /path/to/jpgs -type f -exec jhead -v {} | grep 123 \; -print
Lösung
Versuchen Sie, diese
find /path/to/jpgs -type f -exec sh -c 'jhead -v {} | grep 123' \; -print
Alternativ können Sie versuchen, Ihre exec-Anweisung innerhalb eines sh Skript einbetten und dann tun:
find -exec some_script {} \;
Andere Tipps
Ein etwas anderer Ansatz wäre xargs zu verwenden:
find /path/to/jpgs -type f -print0 | xargs -0 jhead -v | grep 123
, die ich immer ein bisschen leichter gefunden zu verstehen und anzupassen (die -print0 und -0 Argumente notwendig sind, um die Dateinamen Leerzeichen enthalten, fertig zu werden)
Das Macht (nicht getestet) wirksamer sein als die Verwendung von -exec weil es Rohr der Liste der Dateien in xargs und xargs stellt sicher, dass die jhead Kommandozeile nicht zu lange erhalten.
Mit -exec
können Sie nur eine einzige ausführbare Datei mit einigen Argumenten ausführen, nicht beliebige Shell-Kommandos. Um dies zu umgehen, können Sie sh -c '<shell command>'
verwenden.
Sie zu beachten, dass die Verwendung von -exec
ziemlich ineffizient ist. Für jede Datei, die gefunden wird, hat der Befehl erneut ausgeführt werden. Es wäre effizienter, wenn Sie dies vermeiden können. (Zum Beispiel durch die grep
außerhalb des -exec
bewegt oder Rohrleitungen, die Ergebnisse von find
xargs
wie Palmin .)
Mit find
Befehl für diese Art einer Aufgabe ist vielleicht nicht die beste Alternative. Ich verwende den folgenden Befehl häufig Dateien zu finden, die die gewünschten Informationen enthalten:
for i in dist/*.jar; do echo ">> $i"; jar -tf "$i" | grep BeanException; done
Wie diese gibt eine Liste würden Sie nicht:
find /path/to/jpgs -type f -exec jhead -v {} \; | grep 123
oder
find /path/to/jpgs -type f -print -exec jhead -v {} \; | grep 123
Setzen Sie Ihre grep auf den Ergebnissen der finden -exec.
Es ist eine Art eine andere Art und Weise Sie es tun können, aber es ist auch ziemlich Ghetto.
Mit der Shell-Option extquote Sie etwas ähnliches wie das, um exec Sachen und dann eine Pipe an sh finden machen tun können.
root@ifrit findtest # find -type f -exec echo ls $"|" cat \;|sh
filename
root@ifrit findtest # find -type f -exec echo ls $"|" cat $"|" xargs cat\;|sh
h
ich nur dachte, ich würde hinzufügen, dass da zumindest die Art, wie ich es sichtbar gemacht, es war näher an der ursprünglichen Frage des OP der Verwendung von Rohren innerhalb exec.