Eine Reihe von Dateien mit einem Änderungszeitstempel am Ende des Dateinamens umbenennen?

Eine Reihe von Dateien mit einem Änderungszeitstempel am Ende des Dateinamens umbenennen?

Nehmen wir also an, ich habe ein Verzeichnis mit einer Reihe von Dateien wie g.txt, wobei g.txt zuletzt am, sagen wir, 20. Juni 2012 geändert wurde.

Wie kann ich alle Dateien (z. B. g.txt) stapelweise umbenennen und dabei das letzte Änderungsdatum vom 20. Juni 2012 anhängen?

Antwort1

hier ist eine Version von Goldschrafes Einzeiler:

  • verwendet keine Statistik

  • funktioniert mit früheren Versionen von GNU date

  • verarbeitet Leerzeichen in Dateinamen korrekt

  • kommt auch mit Dateinamen klar, die mit einem Bindestrich beginnen

    for f in *; do mv -- "$f" "$f-$(date -r "$f" +%Y%m%d)"; done


Aktualisierung 2021-03-20

Meine Antwort auf diese Frage beschäftigt mich schon seit Jahren (na ja, nur wenn ich mich daran erinnere – an Tagen wie heute, wenn sie wieder ein Upvote bekommt), also aktualisiere ich sie endlich. Meine ursprüngliche Antwort oben funktioniert noch, aber die aktualisierte Antwort unten ist besser.

WiebeliebigBatch-Datei-Umbenennungsvorgang, sollte dies mit demperl renameDienstprogramm, nicht mit einer umständlichen Shell-For-Schleife.

Das Perl-Umbenennungsprogramm ist im Grunde eine spezialisierte Skriptsprache, mit der Sie JEDEN Perl-Code zum Umbenennen von Dateien verwenden können, von einfachen s/search/replace/regulären Ausdrucksoperationen (die für die meisten Umbenennungsaufgaben ausreichen) bis hin zu komplexen mehrzeiligen Skripts.

z.B

rename -n 'BEGIN {use Date::Format};
           die $! unless -f $_;
           next if (m/-\d{8}$/);
           my $ts=(stat($_))[9];
           my $dt=time2str("%Y%m%d",$ts);
           s/$/-$dt/;' *.txt

Dies erfordert nur Perl und das Date::FormatModul (ein Modul, das so nützlich ist, dass es auf jedem System mit Perl installiert werden sollte. IMO ist es zusammen mit dem Date::ParseModul des Autors Graham Barr,sollenTeil der Kernmodulbibliothek von Perl sein, ist es aber nicht, daher müssen Sie es mit cpanoder einem Distributionspaket wie dem Debian- libtimedate-perlPaket installieren).

Übrigens überspringt dieses Skript alle Dateien, deren Dateiname scheinbar bereits ein Datum (also 8 Ziffern) enthält.

oder für eine elegantere Version, die das Datum vor die Dateierweiterung setzt (sofern vorhanden):

rename -n 'BEGIN {use Date::Format; use File::Basename};
           die $! unless -f $_;
           my ($filename,$dirs,$suffix) = fileparse($_,qr/\.[^.]*/);
           next if (m/-\d{8}${suffix}$/);
           my $ts=(stat($_))[9];
           my $dt=time2str("%Y%m%d",$ts);
           s/${suffix}$/-${dt}${suffix}/;' *.txt

Für diese Version gelten keine zusätzlichen Anforderungen, da das File::BasenameModul, soweit ich mich erinnern kann (mindestens ein Jahrzehnt, wahrscheinlich schon länger), als Standard-Kernmodul in Perl enthalten ist.

Notiz:Beide renameoben genannten Skripte verwenden die Option „Dry-Run“ von rename -n(auch bekannt als --nono), sodass die Ergebnisse vor der Anwendung getestet/simuliert werden können. Entfernen Sie -n(oder ersetzen Sie es durch -vfür eine ausführliche Ausgabe), wenn Sie sicher sind, dass es das gewünschte Ergebnis liefert.

Beachten Sie außerdem:wie mit jedem anderen Perl- renameSkript können hiermit Dateinamen umbenannt werden, die in der Befehlszeile und/oder über die Standardeingabe angegeben wurden. So können Sie beispielsweise alle TXT-Dateien im aktuellen Verzeichnis und allen Unterverzeichnissen umbenennen:

find . -type f -iname '*.txt' -print0 | 
   rename -0 --nofullpath -n '..........'

Übrigens habe ich hier die Option rename--nofullpath (auch bekannt als -d, --filenmame, --nopath) von verwendet, um sicherzustellen, dass nur der Dateinamenteil aller gefundenen Dateipfade umbenannt wird. Dies ist in diesem speziellen Fall nicht erforderlich (da die Beispiel-Umbenennungsskripte nur das Ende des Dateinamens ändern), ist aber im Allgemeinen eine gute Idee, wenn Sie den Pfad und den Dateinamen nicht umbenennen möchten (z. B. würde ein Umbenennungsskript, das 's/ //g'Leerzeichen aus Dateinamen entfernen möchte, versuchen, alle Leerzeichen im Pfad sowie im Dateinamen ohne zu entfernen --nofullpath, was wahrscheinlich zu einem Fehler führen würde).

Endlich:verwechseln Sie das Perl-Umbenennungsskript (auch bekannt als File::Rename, oder manchmal prenameunter Fedora und RedHat genannt, oder perl-rename) nicht mit anderen Programmen namens „Umbenennung“. NurDieses Perl-basierte Umbenennungsprogramm kann Dateien mit beliebigem Perl-Code umbenennen, wie oben gezeigt. Jedes andere Umbenennungsprogramm verfügt über andere Funktionen und andere und inkompatible Befehlszeilenoptionen.

Sie können überprüfen, ob Sie die richtige Umbenennung installiert haben:

$ rename -V
/usr/bin/rename using File::Rename version 1.13, File::Rename::Options version 1.10

Die ausführbare Datei heißt auf Ihrem System möglicherweise prenameoder perl-rename. Versuchen Sie es mit diesen Namen und passen Sie die obigen Beispiele an, um den richtigen ausführbaren Namen zu verwenden.file-rename-V

Antwort2

Schneller und einfacher Bash-Einzeiler zum Umbenennen aller (globbierten) Dateien im aktuellen Verzeichnis von filename.txtin filename.txt-20120620:

for f in *; do mv -- "$f" "$f-$(stat -c %Y "$f" | date +%Y%m%d)"; done

Ich bin sicher, ein unternehmungslustiger Bash-Nerd wird einen Grenzfall finden, um es kaputt zu machen. :)

Offensichtlich werden dadurch nicht die gewünschten Dinge erledigt, wie etwa die Überprüfung, ob eine Datei am Ende bereits etwas enthält, das wie ein Datum aussieht.

Antwort3

Obligatorischer zsh-Einzeiler (das einmalige Laden optionaler Komponenten nicht mitgerechnet):

zmodload zsh/stat
autoload -U zmv
zmv -n '(*)' '$1-$(stat -F %Y%m%d +mtime -- $1)'

Wir verwenden das statBuiltin aus demzsh/statModul, und daszmvFunktion zum Umbenennen von Dateien. Und hier ist noch eine Extrafunktion, die das Datum vor die Erweiterung setzt, falls vorhanden.

zmv -n '(*)' '$1:r-$(stat -F %Y%m%d +mtime -- $1)${${1:e}:+.$1:e}'

Antwort4

Hier ist die Version von cas' Oneliner (basierend auf goldschrafes Oneliner), erweitert mitIdempotenz,

ie erweitert um Präfixe für Dateien mit Datum, Uhrzeit undDies ist nur für diejenigen zu tun, die noch kein Datums-/Uhrzeitpräfix haben.

Anwendungsfall: hilfreich, wenn Sie dem Verzeichnis neue Dateien hinzufügen und denjenigen Dateien, die noch keines haben, ein Datums-/Uhrzeitpräfix hinzufügen möchten.

for f in * ; do
  if [[ "$f" != ????-??-??' '??:??:??' - '* ]]; then
    mv -v -- "$f" "$(date -r "$f" +%Y-%m-%d' '%H:%M:%S) - $f" ;
  fi;
done

verwandte Informationen