Meine derzeit beste Wette ist:
for i in $(find . -name *.jpg); do echo $i; done
Problem: behandelt keine Leerzeichen in Dateinamen.
Hinweis: Ich würde auch gerne eine grafische Methode verwenden, z. B. den Befehl "tree".
Meine derzeit beste Wette ist:
for i in $(find . -name *.jpg); do echo $i; done
Problem: behandelt keine Leerzeichen in Dateinamen.
Hinweis: Ich würde auch gerne eine grafische Methode verwenden, z. B. den Befehl "tree".
Antworten:
Der kanonische Weg ist zu tun
find . -name '*.jpg' -exec echo {} \;
(Ersetzen \;
durch +
, um mehr als eine Datei echo
gleichzeitig zu übergeben.)
oder (GNU-spezifisch, obwohl einige BSDs es jetzt auch haben):
find . -name '*.jpg' -print0 | xargs -r0 echo
zsh:
for i (**/*.jpg(D)) echo $i
echo
was Fluchtsequenzen wie \b
(zumindest die Unix-konformen echo
s) erweitert.
find
Manpage wird find . -type f -exec file '{}' \;
im EXAMPLES
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", oder printf '<%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
IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done
Dann sind nur Zeilenumbrüche ein Problem.
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 :
find /path/to/files/ -iname "*jpg" | \
while read I; do
cp -v --parent "$I" /backup/dir/
done
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.
Einfach mit find
und bash
:
find . -name '*.jpg' -exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
' -- {} \;
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):
find . -name '*.jpg' -exec bash -c 'for i do
echo "treating file $i in bash, from path : ${i%/*}"
done' -- {} +
In der letzten Version von Bash können Sie die globstar
Option verwenden:
shopt -s globstar
for file in **/*.jpg ; do
echo "$file"
done
Für einfache Aktionen können Sie die Schleife sogar ganz überspringen:
echo **/*.jpg
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 -L
oder 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?