Wenn Sie mit xargs -0 , sollten Sie es mit Spiel finden -0
itsbruce
1
@ MichaelKjörling, kein Zitat {} macht keinen Unterschied. {} wird durch find erweitert, nicht durch die Shell. Eine Verbesserung wäre nicht zu gebrauchen, echowas Fluchtsequenzen wie \b(zumindest die Unix-konformen echos) erweitert.
Stéphane Chazelas
1
@sch Bist du sicher? Die findManpage wird find . -type f -exec file '{}' \;im EXAMPLESAbschnitt angezeigt . Vielleicht behandeln einige Muscheln Zahnspangen speziell.
QuasarDonkey
1
Zitate schaden nicht, machen aber keinen Unterschied. Alle '{}', \{\}, {}, "{}", '{'}werden von der Shell (was auch immer Bourne-artig Shell) mit einem Argumente erweitert zu finden , dass die beiden Zeichen „{“ und „}“. Ersetzen Sie "find" durch "echo find", oder printf '<%s>\n' findüberprüfen Sie dies noch einmal.
Beachten Sie jedoch, dass Leerzeichen nicht das einzige Problem in dem von Ihnen angegebenen Code sind. Tabulator-, Zeilenvorschub- und Platzhalterzeichen sind ebenfalls ein Problem.
Mit
IFS='
'set-f
for i in $(find .-name '*.jpg');do echo "$i";done
Was Sie erwähnt haben, ist eines der grundlegenden Probleme, mit denen Menschen konfrontiert sind, wenn sie versuchen, Dateinamen zu lesen. Manchmal vergessen Personen mit begrenzten Kenntnissen und einem falschen Verständnis der Datei- und Ordnerstruktur, dass " In UNIX ist alles eine Datei ". Sie verstehen also nicht, dass sie auch mit Leerzeichen umgehen müssen, da der Dateiname aus zwei oder mehr Wörtern mit Leerzeichen bestehen kann.
Lösung: Eine der bekannteren Methoden hierfür ist ein sauberes Lesen .
Wir lesen hier alle vorhandenen Dateien und speichern sie in einer Variablen. Wenn wir das nächste Mal die gewünschte Verarbeitung durchführen, müssen wir diese Variable nur in Anführungszeichen setzen, damit die Dateinamen mit Leerzeichen erhalten bleiben. Dies ist eine der grundlegenden Methoden, die anderen Antworten der anderen hier funktionieren jedoch genauso gut.
Hier lese ich die Dateien, indem ich ihnen den Pfad gebe, und was auch immer ich lese, ich halte sie in einer Variablen I, die ich zu einem späteren Zeitpunkt während der Verarbeitung zitiere, um die Leerzeichen zu erhalten, um sie richtig zu verarbeiten.
"Alles ist eine Datei" bezieht sich auf etwas anderes. Ihre Lösung ist GUN-spezifisch und unterstützt keine Backslash- oder Newline-Zeichen in Dateinamen. "while read" -Schleifen in Shells (IMO) sind oft ein Hinweis auf eine schlechte Shell-Skriptpraxis.
Stéphane Chazelas
@sch: huh, und ich dachte immer, es ist ok. Vielen Dank für den Hinweis. Ich muss es mir wahrscheinlich genauer ansehen.
The Dark Knight
Entschuldigung, ich meinte oben "GNU", nicht "GUN" (es ist das erste Mal, dass ich merke, dass es sich um Anagramme handelt, übrigens ...)
Stéphane Chazelas
1
Einfach mit findund bash:
find .-name '*.jpg'-exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
'--{} \;
Auf diese Weise verwenden wir $1in bash, wie in einem einfachen Skript, nette Perspektiven, um fortgeschrittene (oder nicht fortgeschrittene) Aufgaben auszuführen.
Eine effizientere Methode (um zu vermeiden, dass für jede Datei eine neue Bash gestartet werden muss):
find .-name '*.jpg'-exec bash -c 'for i do
echo "treating file $i in bash, from path : ${i%/*}"
done'--{}+
Während dies in zsh (woher das Feature stammt) und mit ksh93 (mit set -G) funktioniert , sollte es in bash nicht verwendet werden, da die bash-Version (genau wie GNU grep -r) grundlegend kaputt ist, da sie in symbolische Links zu Verzeichnissen (äquivalent zu find -Loder zshs) übergeht ***/*.jpg). Beachten Sie auch, dass im Gegensatz zu find Dotfiles nicht in Dotdirs absteigen (standardmäßig).
$i
? Ich mache das und es funktioniert gut. Stimmt etwas mit diesem Ansatz nicht?Antworten:
Der kanonische Weg ist zu tun
(Ersetzen
\;
durch+
, um mehr als eine Dateiecho
gleichzeitig zu übergeben.)oder (GNU-spezifisch, obwohl einige BSDs es jetzt auch haben):
zsh:
quelle
echo
was Fluchtsequenzen wie\b
(zumindest die Unix-konformenecho
s) erweitert.find
Manpage wirdfind . -type f -exec file '{}' \;
imEXAMPLES
Abschnitt angezeigt . Vielleicht behandeln einige Muscheln Zahnspangen speziell.'{}'
,\{\}
,{}
,"{}"
,'{'}
werden von der Shell (was auch immer Bourne-artig Shell) mit einem Argumente erweitert zu finden , dass die beiden Zeichen „{“ und „}“. Ersetzen Sie "find" durch "echo find", oderprintf '<%s>\n' find
überprüfen Sie dies noch einmal.Bessere Antworten wurden bereits gegeben.
Beachten Sie jedoch, dass Leerzeichen nicht das einzige Problem in dem von Ihnen angegebenen Code sind. Tabulator-, Zeilenvorschub- und Platzhalterzeichen sind ebenfalls ein Problem.
Mit
Dann sind nur Zeilenumbrüche ein Problem.
quelle
Was Sie erwähnt haben, ist eines der grundlegenden Probleme, mit denen Menschen konfrontiert sind, wenn sie versuchen, Dateinamen zu lesen. Manchmal vergessen Personen mit begrenzten Kenntnissen und einem falschen Verständnis der Datei- und Ordnerstruktur, dass " In UNIX ist alles eine Datei ". Sie verstehen also nicht, dass sie auch mit Leerzeichen umgehen müssen, da der Dateiname aus zwei oder mehr Wörtern mit Leerzeichen bestehen kann.
Lösung: Eine der bekannteren Methoden hierfür ist ein sauberes Lesen .
Wir lesen hier alle vorhandenen Dateien und speichern sie in einer Variablen. Wenn wir das nächste Mal die gewünschte Verarbeitung durchführen, müssen wir diese Variable nur in Anführungszeichen setzen, damit die Dateinamen mit Leerzeichen erhalten bleiben. Dies ist eine der grundlegenden Methoden, die anderen Antworten der anderen hier funktionieren jedoch genauso gut.
SKRIPT :
Hier lese ich die Dateien, indem ich ihnen den Pfad gebe, und was auch immer ich lese, ich halte sie in einer Variablen I, die ich zu einem späteren Zeitpunkt während der Verarbeitung zitiere, um die Leerzeichen zu erhalten, um sie richtig zu verarbeiten.
Hoffe das hilft dir irgendwie.
quelle
Einfach mit
find
undbash
:Auf diese Weise verwenden wir
$1
in bash, wie in einem einfachen Skript, nette Perspektiven, um fortgeschrittene (oder nicht fortgeschrittene) Aufgaben auszuführen.Eine effizientere Methode (um zu vermeiden, dass für jede Datei eine neue Bash gestartet werden muss):
quelle
In der letzten Version von Bash können Sie die
globstar
Option verwenden:Für einfache Aktionen können Sie die Schleife sogar ganz überspringen:
quelle
set -G
) funktioniert , sollte es in bash nicht verwendet werden, da die bash-Version (genau wie GNUgrep -r
) grundlegend kaputt ist, da sie in symbolische Links zu Verzeichnissen (äquivalent zufind -L
oder zshs) übergeht***/*.jpg
). Beachten Sie auch, dass im Gegensatz zu find Dotfiles nicht in Dotdirs absteigen (standardmäßig).