Verschieben Sie Dateien nach Datum mithilfe der CLI in ein anderes Verzeichnis

9

Ich habe eine große Anzahl von Bildern von einer alten Festplatte, die ich zu organisieren versuche. Wenn ich ausgeführt werde ls -l, stelle ich fest, dass alle diese Dateien ein Erstellungsdatum von 2012 oder früher haben. Im Idealfall möchte ich diese auf die zweite Festplatte meines Computers verschieben, die nicht automatisch gemountet wird. Am besten könnte ich dies alles als Stapel mit einigen miteinander verknüpften Befehlen tun. Bisher habe ich das, ls -l | grep -i 2012was nur die Dateien mit 2012 in dem von angegebenen Datum ausspuckt ls -l. Der Trick wäre nun cp, alle diese Dateien in das neue Verzeichnis zu verschieben. Ich bin mir nicht sicher, wohin ich als nächstes gehen soll, da jede Datei kopiert werden müsste. Was wäre mein nächster Befehlssatz?

Nerdenator
quelle

Antworten:

12

Nicht verwenden ls. In solchen Fällen wird die Verwendung nicht empfohlen. Darüber hinaus grepist es keine gute Idee, nach Datum zu filtern. Ihr Dateiname enthält möglicherweise selbst eine 2012Zeichenfolge, obwohl diese 2012 nicht geändert wurde.

Verwenden Sie den findBefehl und leiten Sie die Ausgabe weiter.

find . -newermt 20120101 -not -newermt 20130101 -print0 | xargs -0 cp -t /your/target/directory 

Hier,

-newermt 20120101  ==>  File's modified date should be newer than 01 Jan 2012
-not               ==>  reverses the following condition. Hence file should be older than 01 Jan 2013
-print0 and -0     ==>  Use this options so that the command doesn't fail when filenames contain spaces 
Shivams
quelle
1
Wird nicht `-exec mv {} / your / target / directory \; ' anstelle von '-print 0 | xargs -0 cp -t / your / target / directory 'funktionieren genauso gut bei Problemen mit Leerzeichen in Namen? (Auch wollte der OP bewegen nicht kopieren )
Hagen von Eitzen
^^ Ja. Beide erreichen das gleiche Ziel.
Shivams
4

Wenn Sie neuere Dateien auf der alten Festplatte haben, die Sie ignorieren möchten, würde ich so vorgehen

  1. Erstellen Sie eine temporäre Markierungsdatei mit einem Änderungsdatum, das die gewünschten Dateien von den nicht vorhandenen Dateien trennt
  2. Kopieren Sie Dateien, die älter als die Markierungsdatei sind, an den neuen Speicherort

Hier sind Beispielbefehle dafür, bei denen davon ausgegangen wird, dass Sie eine Verzeichnishierarchie von der alten Festplatte in der neuen beibehalten möchten ( cpioist ein Kopierbefehl, ähnlich taroder pax):

touch -t 201201010000 /tmp/marker    # YYYYMMDDhhmm == Jan 1st, 2012
cd /path/to/old/disk
find . -type f \! -newer /tmp/marker -print0 | cpio -pmd0 /path/to/new/disk
Roaima
quelle
2

Ich denke, vielleicht ist dieses Problem das gleiche wie Ihres. Sie können dies auch überprüfen: Erstellen Sie Unterverzeichnisse und organisieren Sie Dateien nach Datum

Ich schreibe dieses neue Skript basierend auf der ersten Antwort dieses Problems:

for x in *; do
  d=$(date -r "$x" +%Y)
  mkdir -p "/your/new/directory/$d"
  mv -- "$x" "/your/new/directory/$d/"
done
  1. Schreiben Sie dieses Skript in eine Datei mit dem Namen copy.shin Ihrem alten Verzeichnis.

  2. Ersetzen Sie den /your/new/directorydurch den Pfad Ihres neuen Verzeichnisses

  3. Machen Sie diese Datei ausführbar mit chmod +x copy.sh

  4. Führen Sie diese Datei dann mit aus ./copy.sh

warmblau
quelle
1
Möglicherweise möchten Sie eine Ausnahmebehandlung hinzufügen, damit sich das Skript nicht selbst in ein 2015Verzeichnis verschiebt.
G-Man sagt "Reinstate Monica"
1

Sie sollten wahrscheinlich ein Batch-Tool für Batch-Vorgänge verwenden. Dies bedeutet normalerweise, dass alle Datensätze in einem einzigen Stream gelesen / geschrieben werden, anstatt beispielsweise cpfür jede kopierte Datei einen eigenen Prozess aufzurufen .

Hier ist bereits eine cpioAntwort geschrieben, die angesichts der bereits angebotenen Optionen wahrscheinlich das ist, was ich wählen würde. Das cpioFormat wurde jedoch paxseit seiner Blütezeit verbessert und in das standardisierte Archivformat integriert. Gleiches gilt für tar.

Ein strikter POSIX- paxbietet wahrscheinlich keine Optionen zum direkten Filtern von Archivmitgliedern basierend auf Dateimodifikationszeiten - obwohl der Standard den Formatmodifikator für den Listenmodus spezifiziert %T. Die am häufigsten verfügbare paxImplementierung, die mir bekannt ist - die von mirabilos verwaltete BSD-Version - erweitert dies jedoch zu einem direkt zugänglichen CLI-Switch.

Zum Beispiel nur alle Dateien im Baum auf verwurzelt zu kopieren ./dem letzten Änderung vor , ccyymmddHHMMum /target/dirSie tun können:

pax -rwT,201301010000 ./ /target/dir

Um zu vermeiden, dass Sie in untergeordnete Verzeichnisse zurückkehren, können Sie stattdessen Folgendes tun:

pax -rwdT,201301010000 ./* /target/dir

Weitere manInformationen finden Sie auf der Seite.

mikeserv
quelle
Ich denke, ich sollte wirklich lernen pax, aber tarund cpiomich trotzdem gut ausstehen. +1
Roaima
@roaima - streng genommen liest / schreibt das von POSIX spezifizierte Dienstprogramm die Formate cpio, pax und ustar , obwohl es ein tatsächliches paxArchivformat gibt (das eine Erweiterung des ustar- Formats darstellt) . Da alle drei Archivtypen in erster Linie nur unterschiedliche Methoden zum Codieren der Metadaten für viele Dateien neben den tatsächlichen Daten dieser Dateien in einem einzigen Stream darstellen, ist dies keine allzu große Anstrengung. Ich habe einmal geschrieben - das waren nur ein paar Zeilen Shell-Skript für - meistens - Blockentwickler im laufenden Betrieb, basierend auf der POSIX-Spezifikation. pax shitarddtar
Mikeserv
Ich mag dein verknüpftes Skript. Seltsamerweise wäre es vor ein paar Monaten für genau diesen Zweck sehr nützlich gewesen. Naja. Ich könnte sogar versuchen, die Verwendung zu beenden cpio -H ustar...
Roaima