【问题标题】:Rename JPG files according to date created根据创建日期重命名 JPG 文件
【发布时间】:2011-01-17 07:01:06
【问题描述】:

我想重命名某个目录中的所有文件。将它们重命名为创建日期。
所以如果我的文件是 Image1.jpg,它应该重命名为“Jan 16 12:09:42 2011.jpg”
我想通过命令行来做到这一点。我一直在尝试:

stat -f %SB Image0100.jpg

但是我怎样才能将它与mv 命令结合起来呢?我将如何遍历整个文件 statmv
或者有没有简单的方法来重命名所有文件的创建日期?

【问题讨论】:

  • 没有简单的方法,但使用 shell 脚本很容易。但是,请考虑在您以这种方式重命名所有文件后,它们将无法在目录列表中正确排序。首先是四月,然后是八月和十二月……这真的是你想要的吗?或者,您想使用像yyyymmdd.hhmmss,jpg 这样的文件名吗?
  • @jim: 不管怎样jim,只要改名就好了。
  • 我赞成 Jim 的建议;使用 ISO 8601 类型格式(例如yyyymmdd.hhmmss.jpg),以便更轻松地按时间顺序查看内容。
  • 未编程...属于超级用户。

标签: linux unix command-line


【解决方案1】:
jhead -n DSCN0382.JPG
DSCN0382.JPG --> 0408-150734.jpg

也可以给出任何 strftime 参数:

jhead -n%Y%m%d-%H%M%S *.jpg 

这会将与 *.jpg 匹配的文件重命名为 YYYYMMDD-HHMMSS 格式

jhead -n%Y%m%d-%H%M%S DSCN0382.JPG
DSCN0382.JPG --> 20120408-150734.jpg

另请参阅手册页以了解许多其他很酷的选项。例如,您可以更正(移动)EXIF 日期。当某些相机的时间设置不正确时,这在合并来自不同相机的文件时非常方便。

【讨论】:

  • 我很快想从手册页中添加:“如果目标名称已经存在,则名称将附加“a”、“b”、“c”等,除非名称结尾带有字母,在这种情况下,它将附加“0”、“1”、“2”等。”
  • 对于 mac 用户,jhead 在 homebrew 上可用并且工作方式相同
  • 谢谢。我喜欢的 jhead 格式字符串如下:jhead -nIMG_%04i_%d-%m-%Y *.jpg,它将生成 IMG_0001_31-12-2014.jpg
【解决方案2】:

如果您正在使用包含 EXIF 数据(即来自数码相机)的 JPG,那么您可以使用以下来获取创建日期而不是统计数据。

exif -t 0x9003 -m Image0100.jpg

根据请求,这里是命令和输出。需要注意的几点:

  • 由于不是每个文件都有 exif 数据,我们想在执行其余命令之前检查 dst 是否有效。
  • exif 的输出有一个空格,它是文件名的 PITA。使用 sed 替换为 '-'。
  • 请注意,我在 mv 之前使用“echo”来测试我的脚本。当您确信它在做正确的事情时,您就可以删除“回声”……您不想像那个把所有文件都炸掉的人一样结束。

命令

for i in *.jpg; do
  dst=$(exif -t 0x9003 -m $i ) &&
  dst_esc=$(echo $dst | sed 's/ /-/g' ) &&
  echo mv $i $dst_esc.jpg
done

输出

'12379632.jpg' does not contain tag 'DateTimeOriginal'.
mv 15084688.jpg 2003:02:28-21:48:54.jpg
mv 15136312.jpg 2003:03:01-10:36:05.jpg
mv 15137960.jpg 2003:03:01-10:36:38.jpg
mv 15140744.jpg 2003:03:01-10:37:46.jpg

【讨论】:

  • +1:有趣……!如果您显示示例输出以及如何从中进行重命名,那就更好了。
  • 我会添加第二个过滤器来删除“:”字符,如果您打算与 Windows 操作系统共享文件,这是必须的! dst_esc=$(echo $dst | sed 's/ /-/g' | sed 's/:/-/g' )
  • 太棒了!通过了很多工具,这是第一个真正起作用的......
【解决方案3】:
for file in *jpg
do
 newfile=$(date "+%b %d %H:%M:%S%Y $file" -d "$(stat -c "%y" $file)")
 mv "$file" "$newfile"
done$

【讨论】:

    【解决方案4】:

    还有:

    rename -v 's/.JPG/.jpeg/' *.JPG
    rename -v 's/.jpeg/.jpg/' *.jpeg
    exiv2 -r'RP_%Y%m%d_%H%M%S' rename *.jpg
    

    以 RP_20120801_063021.jpg 为例。这适用于 Debian Linux(例如 Ubuntu)。

    重命名命令适用于某些图像为 .JPG 或 .jpeg 的情况。无法将 .JPG 直接转换为 .jpg,因为它被解释为相同...

    【讨论】:

    • 互联网上的许多人都在寻找他们中最大问题的答案 - 我如何对我拥有的所有我永远不会看的照片进行分类?尽管由于它们的命名,我的都可以放在同一个文件夹中,但我已将它们分组到名为“2012_01_January_Shenanigans”和“2012_06_Scootland_holiday”的文件夹中,每个文件夹大约有 100 张照片。
    【解决方案5】:

    大多数 POSIX 文件系统不记录创建时间(即使记录了,API 也肯定不会公开它),所以你是 SOL。

    【讨论】:

    • +1:这是完全正确的。有“inode 更改时间”,称为 ctime,它记录 inode 上次更改的时间 - 权限、链接、所有者或……还有“修改时间”或内容上次更改的 mtime。这些是您最接近的近似值,但它们都不是很好,除非有其他一些约束要求文件在创建后不会更改。
    【解决方案6】:
    $ for i in *; do mv "$i" "`stat -f %SB $i`"; done
    

    【讨论】:

    • 文件名有空格怎么办?我试过这段代码,但在文件名上有空格字符的问题。
    • 大声笑我刚试过这个,它吹走了我所有的文件,除了一个
    • 一个容易遇到的问题是,如果你 cp 一个目录用于测试目的。那么,问题在于,除非您执行了cp -p ...,否则所有文件的时间都相同,因此它们最终会在名称上相互别名,而只有最后一个文件仍然存在。嘿,我只是回答问题;我尽量不评论这是否真的是个好主意......
    【解决方案7】:
    find . -type f | xargs stat -f "mv %%N \"%%SB.jpg\"" | awk -F \; '{system $1;}'
    

    【讨论】:

    • 您也可以通过管道传输到“sh”而不是 awk 在每一行上运行“system”。
    【解决方案8】:

    如果你和我一样,因为年纪大了,记不住东西而不得不一遍又一遍地用谷歌搜索,你也可以使用 gThumb,它包含一个批处理重命名器,它运行良好并且有一个旧名称 - > 新名称预览。真不错。

    【讨论】:

    • 所以我实际上再次谷歌搜索并找到了自己的答案。谢谢三 :) 顺便说一句,选择您要重命名的所有图片并按 F2。而已。我的首选格式是: %M{%Y-%m-%d_%H-%M-%S}%E 转换为类似 2015-06-06_18-48-46.jpg
    【解决方案9】:

    在带有 Bash 的 MacOS X 10.6.6(以及,我认为,带有 Korn shell)上,这适用于其中包含空格的文件名:

    echo > "x y"
    for file in *
    do
        x=$(stat -f '%SB' -t '%Y%m%d.%H%M%S' "$file")
        mv "$file" "$x"
    done
    

    它还使用从 ISO 8601 派生的符号来表示日期和时间。显然,如果两个文件具有相同的修改时间,那么按字母顺序排列的最后一个文件将是唯一有效的。这也会丢失任何后缀。如果您正在处理“.jpg”文件,您可能希望使用:

    echo > "x y,jpg"
    for file in *.jpg
    do
        x=$(stat -f '%SB' -t '%Y%m%d.%H%M%S.jpg' "$file")
        mv "$file" "$x"
    done
    

    由于输出名称 ($x) 中没有空格,因此移动命令中不需要在 "$x" 周围加上引号,但它们的存在是一致的。

    【讨论】:

      【解决方案10】:

      只需使用exiftool。以下是来自its documentation 的示例:

         exiftool -r '-FileName<CreateDate' -d %Y-%m-%d/%H%M_%%f.%%e dir
              Both the directory and the filename may be changed together via the
              "FileName" tag if the new "FileName" contains a '/'.  The example above
              recursively renames all images in a directory by adding a "CreateDate"
              timestamp to the start of the filename, then moves them into new
              directories named by date.
      

      【讨论】:

        【解决方案11】:

        perl 替代方案:

        我真的很喜欢用 perl 添加固定字符串前缀的短模式:

        /bin/ls *.jpg | perl -pe 's/.*/mv "$&" "prefix_$&"/' | sh
        

        做一个日期前缀,有点复杂。

        cat >t.pl
        
        while(<*.jpg>) {
            $mtime = (stat($_))[9];
            ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($mtime);
            $year += 1900;
            ++ $mon;
            printf("mv \"%s\" \"%d-%.2d-%.2d-%s\"\n", $_, $year, $mon, $mday, $_)
        }
        
        perl t.pl | sh
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-14
          • 1970-01-01
          • 1970-01-01
          • 2018-02-06
          • 1970-01-01
          • 2013-05-08
          相关资源
          最近更新 更多