Wenn ich in Shotwell Bilder von meiner Kamera importiere, werden auch die Videoclips importiert. Das ist etwas nervig, da ich meine Videos in einem anderen Ordner speichern möchte. Ich habe versucht, einen Bash-Befehl zu schreiben, habe aber keinen Erfolg gehabt.
Ich benötige einen Befehl, der die folgenden Anforderungen erfüllt:
- Suchen Sie alle Dateien in einer Verzeichnisstruktur, die nicht die Erweiterung .jpg, .png, .gif oder .xcf haben (ohne Berücksichtigung der Groß- und Kleinschreibung).
- Verschieben Sie alle diese Dateien in ein Zielverzeichnis, unabhängig davon, ob die Dateinamen oder Verzeichnispfade Leerzeichen oder Sonderzeichen enthalten.
Jede Hilfe wäre dankbar!
BEARBEITEN: Ich verwende die Standard-Shell in Ubuntu, was bedeutet, dass einige Befehle Aliasing usw. sind.
EDIT 2: Ich habe es selbst versucht (nicht der Kopierteil, nur die Auflistung der Dateien). Ich habe extglob aktiviert und den folgenden Befehl ausgeführt:
$ ls -R /path | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }'
Dies listet alles auf. Ich habe versucht, grep am Ende zu verwenden, habe aber nicht die geringste Ahnung, wie ich es dazu bringen kann, dass es nicht mit einem Muster übereinstimmt, das ich ihm gebe. Der extglob-Schalter hat bei grep nicht viel geholfen, obwohl er bei anderen Befehlen hilft.
Antworten:
Sie können verwenden
find
, um alle Dateien in einem Verzeichnisbaum zu finden, die mit bestimmten Tests übereinstimmen (oder nicht übereinstimmen), und dann etwas damit zu tun. Für dieses spezielle Problem können Sie Folgendes verwenden:Dies beschränkt die Suche auf reguläre Dateien (
-type f
) und dann auf Dateien, deren Namen in keinem Fall ( ) oder ( )!
die Erweiterung haben ( ) usw.). Alle Erweiterungen sind in einer einzigen Bedingung zwischen gruppiert . Für jede übereinstimmende Datei wird ein Befehl ( ) ausgeführt, der die Datei, deren Name anstelle von eingefügt wird , in das Verzeichnis verschiebt . Das sagt, dass der Befehl beendet ist.*.png
-iname '*.png'
-o
*.gif
\( ... \)
-exec
{}
/new/path
\;
find
Die Namensersetzung erfolgt innerhalb des Programmausführungscodes, sodass Leerzeichen und andere Sonderzeichen keine Rolle spielen.
Wenn Sie dies nur in Bash tun möchten, können Sie die erweiterten Mustervergleichsfunktionen von Bash verwenden . Diese erfordern, dass eingeschaltet
shopt extglob
ist, undglobstar
auch. Verwenden Sie in diesem Fall:Dies stimmt mit allen Dateien in Unterverzeichnissen (
**
) überein*.gif
, die*.png
in keiner Kombination von Zeichenfällen usw. übereinstimmen , und verschiebt sie in den neuen Pfad. Die Erweiterung wird von der Shell durchgeführt, sodass Leerzeichen und Sonderzeichen keine Rolle mehr spielen.Oben wird davon ausgegangen, dass sich alle Dateien in Unterverzeichnissen befinden. Wenn nicht, können Sie den Teil danach wiederholen
**/
, um auch das aktuelle Verzeichnis einzuschließen.Es gibt ähnliche Funktionen in
zsh
und anderen Shells, aber Sie haben angegeben, dass Sie Bash verwenden.(Ein weiterer Hinweis: Parsen
ls
ist niemals eine gute Idee - probieren Sie es einfach nicht aus.)quelle
-exec mv {} +
. Auch - du liegst falschls
. Es macht das Gegenteilfind
.find
findetls
Listen. Es analysiert sich übrigens von selbst. Und selbst wenn das, was ich sage, nicht wahr ist, machen Sie sicher keinen Versuch, Ihre pauschale Aussage zu sichern. Und bitte verlinken Sie nicht auf dieses Wooledge-Wiki-Ding - es ist eine schreckliche Informationsquelle - und nicht nur auf dieser Seite. Hier ist meinerseits ein gutes Beispiel dafür, wie einfach esls
ist, analysiert zu werden. Übrigens - es würde dort genauso funktionieren, wenn es sich um Zeilenumbrüche und nicht um Leerzeichen handelt+
, aber es spielt wirklich keine Rolle und es ist viel weniger klar. Ich dachte, es könnte die falsche Antwort sein, da ich hier nicht auf Wooledge verlinkt habe (obwohl ich in anderen Antworten zweifellos gelesen habe), so dass "diese Seite" wie eine baumelnde Referenz erscheint.ls
übrigens zeigt, wie einfach es ist, analysiert zu werden, aber ich denke, wir unterscheiden uns darin, wie einfach das ist - das war eine Menge kluger Arbeit. "Niemals tun" ist also immer noch ein guter allgemeiner Rat an alle, die Rat brauchenSie verwenden Ubuntu, damit Sie GNU finden können. Versuchen Sie:
-iregex
Verwenden Sie Regex, um den Dateinamen zu finden. Wenn Sie jedoch die Groß- und Kleinschreibung nicht!
berücksichtigen, wird der Regex negiert.-exec command +
Befehl für übereinstimmende Dateien ausführen. Es ist wiefind -print0
mitxargs -0
. Auf diese Weise können wir mehrere mit einemmv
Befehl gefundene Dateien verschieben , sodass die Gesamtzahl der Aufrufbefehle geringer ist als die Anzahl der übereinstimmenden Dateien.-maxdepth 1
Beschränken Siefind
die Suche nur im aktuellen Verzeichnis. Wenn Sie rekursiv arbeiten möchten, entfernen Sie es.quelle
Es besteht keine Notwendigkeit, dies zu komplizieren! Warum nicht einfach:
Dies funktioniert natürlich nicht für einen ganzen Verzeichnisbaum, sondern nur für ein flaches Verzeichnis von Dateien.
quelle