Files

重命名文件名末尾帶有日期修改時間戳的一堆文件?

  • March 20, 2021

所以,比如說,我有一個目錄,裡面有一堆像 g.txt 這樣的文件,其中 g.txt 最後一次修改是在 2012 年 6 月 20 日。

如何批量重命名所有文件(如 g.txt),最後修改日期為 2012 年 6 月 20 日?

快速而骯髒的 Bash 單線將目前目錄中的所有(全域)文件重命名filename.txtfilename.txt-20120620

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

我敢肯定,一個有進取心的 Bash 書呆子會找到一些邊緣案例來打破它。:)

顯然,這並不能做一些理想的事情,例如檢查文件是否已經有一些看起來像最後的日期。

這是 goldschrafe 的單線版本:

  • 不使用統計
  • 適用於早期版本的 GNU date
  • 正確處理文件名中的任何空格
  • 還可以處理以破折號開頭的文件名

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


2021-03-20 更新

我對這個問題的回答多年來一直困擾著我(嗯,只有當我記得它時——在今天這樣的日子裡,當它得到另一個支持時)所以我終於更新了它。我上面的原始答案仍然有效,但下面的更新答案更好。

任何批處理文件重命名操作一樣,這應該使用perl rename實用程序來完成,而不是使用一些笨拙的 shell for 循環。

perl rename 實用程序實際上是一種專門的腳本語言,它允許您使用任何 perl 程式碼來重命名文件,從簡單的s/search/replace/正則表達式操作(足以完成大多數重命名任務)到復雜的多行腳本。

例如

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

這只需要 perl 和Date::Format模組(一個非常有用的模組,它應該安裝在任何帶有 perl 的系統上。IMO 它,連同作者 Graham Barr 的Date::Parse模組,應該是 perl 核心模組庫的一部分,但事實並非如此您必須使用cpan發行版軟體包(如 Debian 的libtimedate-perl軟體包)安裝它)。

順便說一句,這個腳本會跳過任何看起來在文件名末尾已經有日期(即 8 位)的文件。

或者,對於將日期放在文件後綴(如果有)之前的更高級的版本:

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

這個版本沒有額外的要求,因為File::Basename只要我記得(至少十年,可能更長),該模組就已作為 perl 的標準核心模組包含在內。

**注意:**上面的兩個rename腳本都使用重命名-n(又名--nono)“試執行”選項,以便在應用之前可以測試/模擬結果。當您確定它執行您想要的操作時,刪除-n(或將其替換為詳細輸出)。-v

**另請注意:**與任何其他 perlrename腳本一樣,這可以重命名命令行和/或標準輸入中提供的文件名。例如重命名目前目錄和所有子目錄中的所有 .txt 文件:

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

順便說一句,我在這裡使用了rename’s –nofullpath (aka -d, --filenmame, --nopath) 選項來確保它只重命名找到的任何文件路徑的文件名部分。在這種特殊情況下不需要它(因為範例重命名腳本僅更改文件名的結尾)但當您不想重命名路徑和文件名時通常是一個好主意(例如重命名腳本喜歡's/ //g'剝離文件名中的空格會嘗試刪除路徑中的任何空格以及不帶 的文件名--nofullpath,這可能會導致它失敗並出現錯誤)。

**最後:**不要將 perl 重命名腳本(又名File::Rename,或有時prename在 Fedora 和 RedHat 上呼叫,或perl-rename)與任何其他名為 rename 的程序混淆。 只有這個基於 perl 的重命名實用程序可以使用任意 perl 程式碼重命名文件,如上所示,任何其他重命名實用程序將具有不同的功能和不同且不兼容的命令行選項。

您可以檢查是否安裝了正確的重命名:

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

執行檔可能在您的系統上被呼叫prenameor perl-renamefile-rename因此請嘗試-V使用這些文件,並調整上面的範例以使用正確的執行檔名稱。

引用自:https://unix.stackexchange.com/questions/43338