Der find
Der Befehl kann in einfachen Fällen, in denen Sie Operationen mit Wildcard- (oder komplexeren) Dateinamenübereinstimmungen ausführen möchten, ziemlich kurz verwendet werden. Die folgende Technik kann man sich merken ... fast !
Dies funktioniert, indem Sie die find
Befehl führt für jeden gefundenen Dateinamen einen weiteren Befehl aus. Sie können dieses Beispiel mit echo
testen statt/vor mv
.
Wenn wir alle Dateien im aktuellen Verzeichnis, deren Name mit „report“ beginnt, in ein anderes paralleles Verzeichnis namens „reports“ verschieben möchten:
find . -name "report*.*" -exec mv '{}' ../reports/ \;
Die Platzhalterzeichenfolge muss in Anführungszeichen gesetzt werden, das {}, das den Dateinamen markiert, der 'gefunden' wurde, muss in Anführungszeichen gesetzt werden, und das abschließende Semikolon muss mit Escapezeichen versehen werden - alles aufgrund der Bash/Shell-Behandlung dieser Zeichen.
Sehen Sie sich die Manpage für find
an für weitere Anwendungen:https://linux.die.net/man/1/find
Lassen Sie uns kurz darüber sprechen, wie Platzhalter funktionieren.
cp *.txt foo
ruft nicht wirklich cp
auf mit einem Argument *.txt
, wenn Dateien vorhanden sind, die zu diesem Glob passen. Stattdessen läuft es ungefähr so ab:
cp a.txt b.txt c.txt foo
Ebenso etwas wie
mv *.txt *.old
...kann unmöglich wissen, was zu tun ist, denn wenn es aufgerufen wird, sieht es Folgendes:
mv a.txt b.txt c.txt *.old
oder, noch schlimmer, wenn Sie es bereits haben eine Datei namens z.old
, es wird Folgendes angezeigt:
mv a.txt b.txt c.txt z.old
Daher müssen Sie verschiedene Tools verwenden. Bedenken Sie:
# REPLACES: mv /data/*/Sample_*/logs/*_Data_time.err /data/*/Sample_*/logs/*_Data_time_orig.err
for f in /data/*/Sample_*/logs/*_Data_time.err; do
mv "$f" "${f%_Data_time.err}_Data_time_orig.err"
done
# REPLACES: cp /data/*/Sample_*/scripts/*.sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*.sh; do
cp "$f" "${f%.sh}_orig.sh"
done
# REPLACES: sh /data/*/Sample_*/scripts/*_orig.sh
for f in /data/*/Sample_*/scripts/*_orig.sh; do
if [[ -e "$f" ]]; then
# honor the script's shebang and let it choose an interpreter to use
"$f"
else
# script is not executable, assume POSIX sh (not bash, ksh, etc)
sh "$f"
fi
done
Dies verwendet eine Parametererweiterung, um das Ende des alten Namens abzustreifen, bevor der neue Name hinzugefügt wird.