Ich versuche, Dateien vom Terminal zu verschieben, aber nur die aus den Ergebnissen einer grep
Abfrage.
ls -l | grep -i s02 | mv
Wie vervollständige ich den obigen Befehl am besten?
Sie können dies erreichen, indem Sie einfach laufen
cd directory/containing/the/files
mv *[sS]02* /path/to/target/
Für komplexere Operationen gibt es auch die Option, find
alle relevanten Dateien zu finden. Das Beispiel aus Ihrer Frage könnte auch geschrieben werden als
cd directory/containing/the/files
find . -type f -maxdepth 1 -iname '*s02*' -exec mv {} /path/to/target/directory/ \;
Es lohnt sich, einen Blick auf zu werfen, man find
um zu sehen, welche anderen Optionen verfügbar sind.
Zum Beispiel mit bash. Angesichts der folgenden Dateien
$ ls -1
test1
test2
test3
1) Um Überraschungen zu vermeiden, werfen wir zunächst einen Blick auf die Befehle
$ for i in test*; do echo mv $i $i.ext; done
mv test1 test1.ext
mv test2 test2.ext
mv test3 test3.ext
und die Befehle ausführen, wenn wir dies wollen
$ for i in test*; do mv $i $i.ext; done
$ ls -1
test1.ext
test2.ext
test3.ext
Passen Sie den Pfad an Ihre Bedürfnisse an.
2) Es ist möglich, sed und xargs zu verwenden . Testen wir es zuerst
$ ls -1 test* | sed 'p;s/test/test_/' | xargs -n2 printf "%s %s\n"
test2 test_2
test1 test_1
test3 test_3
und die Befehle ausführen, wenn wir dies wollen
$ ls -1 test* | sed 'p;s/test/test_/' | xargs -n2 mv
$ ls -1
test_1
test_2
test_3
Leerzeichen im Dateinamen
Diese Skripte funktionieren nicht wie erwartet, wenn die Dateinamen Leerzeichen enthalten. In Unix wird Leerzeichen als Trennzeichen verwendet. Zum Beispiel mit den Dateien
$ ls -1
test 1
test 2
test 3
Es ist klar, dass die folgenden Befehle nicht wie erwartet funktionieren können
$ for i in test*; do echo mv $i $i.ext; done
mv test 1 test 1.ext
mv test 2 test 2.ext
mv test 3 test 3.ext
Die Lösung besteht darin, das Leerzeichen aus der Liste der Trennzeichen auszuschließen
$ IFS="`printf '\n\t'`"
und stellen Sie es den Befehlen voran, die die Dateinamen mit Leerzeichen verarbeiten sollen. Der Befehl unten
$ IFS="`printf '\n\t'`"; for i in test*; do mv $i $i.ext; done
funktioniert wie erwartet
$ ls -1
test 1.ext
test 2.ext
test 3.ext
Die nächste Option ist das Zitieren der Argumente
for i in test*; do mv "$i" "$i.ext"; done
Auf diese Weise ist es möglich, die Vielfalt der Unix-Filter zu nutzen und die Beschränkung auf das Konstrukt "find ... -exec ... {}" zu umgehen. Weitere Einschränkungen finden Sie in den Hinweisen unter der Zeile.
Hinweise zu macOS
1) Zitat von opengroup.org - Produktstandard: Befehle und Dienstprogramme V4
1.4.21 sh
Frage 31: Wird die Umgebungsvariable IFS beim Aufruf der Shell ignoriert?
Antwort: Ja
Begründung: Die Spezifikation lässt zu, dass der Befehl sh die Einstellung der IFS-Umgebungsvariablen beim Aufruf ignoriert. Die Einstellung dieser Variablen wurde verwendet, um die Sicherheit auf Systemen zu verletzen, die die Shell verwenden, um einen Aufruf an die Schnittstellen system() und execvp() zu interpretieren.
Referenz: Technischer Standard, Shell and Utilities, Ausgabe 6, Kapitel 4, Utilities, sh, ENVIRONMENT VARIABLES, IFS.
2) Zitieren von developer.apple.com - Shell Input und Output
Sie können das Verhalten des Lesebefehls ändern, indem Sie die Shell-Variable IFS (kurz für interne Feldtrennzeichen) ändern. Das Standardverhalten besteht darin, Eingaben überall dort aufzuteilen, wo ein Leerzeichen, ein Tabulator oder ein Zeilenumbruch vorhanden ist. Durch Ändern dieser Variable ...
3) Zitieren von developer.apple.com - Basic Control Statements - Standard for Loops
Im nächsten Beispiel ist die Liste *.JPG ...
#!/bin/sh
for i in *.JPG ; do
mv "$i" "$(echo $i | sed 's/\.JPG$/.x/')"
mv "$(echo $i | sed 's/\.JPG$/.x/')" "$(echo $i | sed 's/\.JPG$/.jpg/')"
done
test 1
und similar fehl. Es wird auch nicht das tun, was Sie erwarten, wenn das aktuelle Verzeichnis Dateien enthält, deren Namen mit beginnen test
.\0
Zeichenfolgen mit -terminiert sind, und sich um das Setzen/Verwenden von Variablen kümmern. Siehe mywiki.wooledge.org/BashPitfalls und mywiki.wooledge.org/BashFAQ :-)for
Schleife über das Ergebnis von zu verwenden find
. Die Verwendung find ... -exec
(kombiniert mit xargs
und/oder sh -c
) ist die kanonische Unix-Methode, um solche Dinge zu tun.
kein Hang