Ich habe Millionen von Dateien mit der folgenden Nomenklatur auf einem Linux-Computer:
1559704165_a1ac6f55fef555ee.jpg
Die ersten 10 Ziffern sind Zeitstempel und diejenigen, denen ein folgt, _
sind spezifische IDs. Ich möchte alle Dateien, die mit bestimmten Dateinamen-IDs übereinstimmen, in einen anderen Ordner verschieben.
Ich habe dies im Verzeichnis mit Dateien versucht
find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"
Ich erhalte jedoch eine Fehlermeldung:
bash 1559704165_a1ac6f55fef555ee.jpg: command not found
Wenn ich es versucht habe, mv ??????????_a1ac*.jpg
erhalte ich einen zu langen Fehler in der Argumentliste. Ich habe mindestens 15 verschiedene Dateinamenmuster. Wie bewege ich sie?
| ??????????_a1ac*.jpg
:: Bash erweitert ihn auf mehrere Dateinamen, die erste ist1559704165_a1ac6f55fef555ee.jpg
, wenn Sie am Ende sind In dieser zweiten Pipe-Phase haben1559704165_a1ac6f55fef555ee.jpg next_matching_filename 3rd_matching_filename ... nth_matching_filename
Sie versucht, Folgendes auszuführen: Ich denke, Sie haben stattdessen versucht, nach diesem Dateinamen zu filtern (siehe Antworten unten)Antworten:
Du solltest benutzen:
Das
maxdepth 1
heißt also, dass Sie im aktuellen Verzeichnis keine Unterverzeichnisse suchen möchten.type f
bedeutet, nur Dateien zu finden.name '??????????_a1ac*.jpg'
ist ein Muster, das mit der gesuchten Datei übereinstimmt.mv -t destination "{}" +
bedeutet, übereinstimmende Dateien an das Ziel zu verschieben. Hier werden+
neue übereinstimmende Dateien zu vorherigen hinzugefügt, wie:Hier abcd sind verschiedene Dateien.
quelle
-t
es sich um eine GNU-Erweiterung handelt und daher möglicherweise nicht für andere Arten von UNIX-Derivaten verfügbar ist."{}"
. In diesem Fall möchte ich darauf hinweisen, dass dies{}
nicht durch die Shell erweitert wird und nicht zitiert werden muss. Die Shell geht vorbei{}
, um zu finden und zu sehen,{}
und ersetzt sie durch Pfadnamen. Find exec verwendet den Shell-Parser nicht und führt keine eigene Wortteilung durch. Das Zitieren schadet nicht, es ist nur so, dass die Begründung etwas ungenau ist.Dein Befehl,
Leitet die Liste aller Dateien an alle Dateien weiter!
wird den Trick machen.
quelle
Du bist sehr nah. Sie sollten die
-name
Option verwenden, umfind
. Und denken Sie daran, das Muster zu zitieren.So
quelle
-print0
als letztes Argument zum Suchen hinzufügen (anstelle des Standardarguments: -print) und-0
xargs als erste Option hinzufügen (dh :)xargs -0 mv -t "/home/ubuntu/ntest"
. Auf diese Weise können alle Arten von seltsamen Dateinamen (mit Leerzeichen, "Zeilenumbruch" usw.) behandelt werden.find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' -print0 |xargs -0 mv -t "/home/ubuntu/ntest"
(funktioniert nur mit GNU-ähnlichen Fund)Nicht so "gut" wie die
find
Lösungen, aber eine andere gültige Lösung besteht darin, diemv
Befehle detaillierter zu gestalten.Dies führt 4096 Verschiebungen durch, wobei weniger
mv
Operationen pro Operation verschoben werden.quelle
find
(aus welchem Grund auch immer).Wenn Sie Dateien auf demselben Hostsystem verschieben möchten, was Sie wahrscheinlich mit Ihrem tun
mv
,rsync
könnte dies eine schnellere Option sein:--inplace
und-W
sollen den Prozess beschleunigen.Sollte dies zu einem zu langen Fehler einer anderen Argumentliste führen, können Sie Listen füttern
rsync
Machen Sie die Liste zum Beispiel mit find
und gib es
rsync
Die Quelle hier ist
/path/to/files
, weilrsync
die Liste, die Sie geben, als relativ zu Ihrer Quelle behandelt wird.Der Punkt ist:
rsync
ist schneller alsmv
, wenn sich die Dateien nicht im selben Dateisystem befinden .quelle
find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txt
an rsync mit übergeben--files-from=/tmp/my_image_list.txt
. Der Punkt ist, dassrsync
schneller ist. Es sei denn, die Dateien befinden sich auf demselben Dateisystem, das OP nicht angegeben hat.