Ich versuche, ein Array zu verwenden, um eine Liste von Dateinamen mit dem find
Befehl zu speichern .
Aus irgendeinem Grund funktioniert das Array in der von der Schule verwendeten Bash nicht, mein Programm funktioniert jedoch auf meinem eigenen Laptop.
Also habe ich mich gefragt, ob es einen anderen Weg gibt, das ist, was ich habe:
array = (`find . -name "*.txt"`) #this will store all the .txt files into the array
Dann kann ich mit dem Befehl cat auf die Array-Elemente zugreifen und Kopien aller Dateien erstellen.
Gibt es eine andere Möglichkeit, dies ohne Verwendung eines Arrays zu tun?
-type f
. Es ist gültig, ein Verzeichnis mit der Endung .txt zu haben, z. dir.txtAntworten:
Sie könnten so etwas gebrauchen:
find . -name '*.txt' | while read line; do echo "Processing file '$line'" done
ZB eine Kopie machen:
find . -name '*.txt' | while read line; do echo "Copying '$line' to /tmp" cp -- "$line" /tmp done
HTH
quelle
for
Schleife ist hier definitiv die bessere Wahl. Die Verwendung eines Arrays würde funktionieren, außer dass es die gesamte Liste in eine Variable liest und dann über die Variable iteriert. Diese Version liest jeden Dateinamen so wie er stammtfind
und verarbeitet ihn inline.a b.txt
.a=1; seq 3 | while read line; do a=2; done; echo $a
druckt1
while
in einer Subshell ausgeführt, da dies der zweite Befehl in der Pipeline ist. Daher sind Änderungen, die in dieser Schleife vorgenommen wurden, nach dem Beenden der Schleife nicht verfügbar. Ich hatte Probleme, dies an eine Variable anzuhängen, die außerhalb der Schleife deklariert wurde. Von hier: stackoverflow.com/questions/22691436/…Ich hatte ein Problem mit der Lösung von Johannes Weiß. Wenn ich nur ein Echo machen würde, würde es für die vollständige Liste der Dateien funktionieren. Wenn ich jedoch versuchen würde, ffmpeg in der nächsten Zeile auszuführen, würde das Skript nur die erste Datei verarbeiten, auf die es gestoßen ist. Ich nahm aufgrund der Pipe ein lustiges IFS-Geschäft an, konnte es aber nicht herausfinden und lief stattdessen mit einer for-Schleife:
for i in $(find . -name '*.mov' ); do echo "$i" done
quelle
Ich denke, Starpause hat die sauberste Lösung, schlägt jedoch fehl, wenn Leerzeichen in Pfaden vorhanden sind. Dies wird durch Einstellung behoben
IFS
. Die richtige Antwort lautet daher:IFS=$'\n' for i in $(find . -name '*.mov' ); do echo "$i" done unset IFS
Sie deaktivieren IFS, um das Verhalten für IFS zurückzusetzen, und warum dies
$
erforderlich istIFS=$'\n'
, finden Sie unter /unix/184863/what-is-the-meaning-of-ifs-n-in- Bash-Scriptingquelle
Setzen Sie nur keine Leerzeichen um das Gleichheitszeichen:
ar=($(find . -name "*.txt"))
Vermeiden Sie nach Möglichkeit Backticks, da diese veraltet sind. Sie können leicht mit Apostroph verwechselt werden, insbesondere in schlechten Schriftarten, und sie nisten nicht so gut.
In den meisten Fällen sind Sie am besten bedient, wenn Sie ein Suchergebnis direkt mit -exec, -execdir, -ok oder -okdir durchlaufen.
Für und während Schleifen sind schwer richtig zu machen, wenn es um Leerzeichen in Dateinamen oder Zeilenumbrüchen und Tabulatoren geht.
find ./ -name "*.txt" -exec grep {} ";"
Das {} muss nicht maskiert werden. Sie werden häufig eine Kombination aus find / xargs sehen, die auch einen zusätzlichen Prozess startet:
find ./ -name "*.txt" | xargs grep {} ";"
quelle
find . -name '*.txt' | while IFS= read -r FILE; do echo "Copying $FILE.." cp "$FILE" /destination done
quelle