Seu*_*eul 7 bash date rename gawk
由于从我第一次提问时不知道的前两个答案和评论中学到的东西,这个问题被完全重写。
拍完照片后,我带着看起来像_DSC1234.NEF. NEF是尼康的相机原始文件格式,因此文件EXIF中存在数据。
我想用三个部分自动重命名它们:
YYYYMMDD所以最终的文件名应该是这样的
20140707_NameOfShoot_0001.NEF
有几个问题:
ad 1.创建日期
有时我只能在拍摄后几天复制和重命名文件,所以日期应该反映照片的拍摄日期,而不是复制日期。mtime似乎是最好的选择,或者如果可能的话,创建日期从EXIF.
广告 2:拍摄名称 理想情况下,这将是一个变量,我可以在调用脚本时将其设置为参数。
广告 3. 图像数量
这应该反映图像的年龄,最旧的数字最小。问题是相机通常会在点击0000后重新开始编号9999。所以9995-9999可能比0000-0004. 我正在寻找反映文件年龄的解决方案,在这种特殊情况下会重命名
同样,mtime如果可能的话,创建日期EXIF似乎是正确的。
从这里我有一个工作解决方案,它按日期重命名文件夹中的所有 .NEF 文件:
find -name '*.NEF' |
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.NEF\n", $0, a++ }' |
bash
Run Code Online (Sandbox Code Playgroud)
硬编码文件修改日期和拍摄名称效果很好,但如果它可以自动化就太好了。
对于时间戳,我在strftime(),上找到了文章mktime(),systime()但我不明白如何使用它们来返回文件修改日期。我还尝试添加DATE=$(date +"%Y%m%d")和添加$DATE到 gawk 行,这会导致删除当前文件夹中的所有文件(并且可能是 systime 并且不会更改时间)。
对于变量,我试过
gawk 'BEGIN{ a=1 }{ printf "mv %s $1_%04d.NEF\n", $0, a++ }' |
Run Code Online (Sandbox Code Playgroud)
并使用 调用脚本./rename FOO,但在重命名时忽略 FOO。
大多数 unices 不跟踪文件的创建日期¹。“创建日期”无论如何定义不明确(复制文件会创建新文件吗?)。您可以使用文件的修改时间,根据合理的解释,这是创建数据的最新版本的日期。如果您制作文件的副本,请确保保留修改时间(例如,cp -p或者cp -a如果您使用cp命令,而不是 bare cp)。
一些文件格式在文件内有一个字段,创建者应用程序在其中填写创建日期。照片通常是这种情况,相机会在 JPEG 或 TIFF 图像中填充一些Exif数据,包括创建时间。尼康的 NEF 图像格式环绕 TIFF 并支持 Exif。
有现成的工具可以重命名包含 Exif 数据的图像文件,以在文件名中包含创建日期。重命名图像以在名称中包含创建日期显示了两种解决方案,即exiftool和exiv2。
我认为这两种工具都不能让您在文件名中包含计数器。您可以分两次进行重命名:首先在文件名中包含日期(以尽可能高的分辨率保留顺序),然后根据该日期部分对文件进行编号(并去掉时间)。由于现代数码单反相机可以连续拍摄图像(尼康的 D4s 以 11fps 的速度拍摄),因此建议在第一阶段也保留原始文件名,否则可能会导致多个文件具有相同的文件名。
exiv2 mv -r %Y%m%d-%H%M%S:basename: *.NEF
# exiv2 uses `strftime(3)`, so `%Y%m%d-%H%M%S` returns YYYYMMDD-hhmmss
# :basename: is a naming variable exiv2's `-r`-handle provides. See `exiv2 -h` for more
# Now you have files with names like 20140630-235958_DSCC1234.NEF.
# Note that chronological order and lexicographic order agree with this naming format.
i=10000
for x in *.NEF; do
i=$((i+1))
mv "$x" "${x%-*}_FOO_${i#1}.NEF"
done
Run Code Online (Sandbox Code Playgroud)
${x%-*}删除-字符后面的部分。计数器变量i从 10000 开始计数,并在1去掉前导数字的情况下使用;这是获取前导零以便所有计数器值具有相同数字的技巧。
通过增加文件名中的数字来重命名文件还有其他解决方案可以重命名一堆文件以包含计数器。
如果您想使用文件的时间戳而不是 Exif 数据,请参阅在文件名末尾使用修改日期时间戳重命名一堆文件?
作为一般注意事项,不要生成 shell 代码,然后将其通过管道传输到 shell 中。这是不必要的复杂。例如,代替
find -name '*.NEF' |
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.NEF\n", $0, a++ }' |
bash
Run Code Online (Sandbox Code Playgroud)
你可以写
find -name '*.NEF' |
gawk 'BEGIN{ a=1 }{ system(sprintf("mv %s %04d.NEF\n", $0, a++)) }'
Run Code Online (Sandbox Code Playgroud)
请注意,如果文件名包含 shell 特殊字符(例如空格'、$、`、 等),这两个版本都可能导致灾难性的结果,因为文件名被解释为 shell 代码。有多种方法可以将其转换为健壮的代码,但这不是最简单的方法,因此我不会采用这种方法。
¹请注意,有一种叫做“ctime”的东西,但c它不是为了创造,而是为了改变。每次有关文件的任何更改时,ctime 都会更改,无论是在其内容还是在其元数据(名称、权限等)。ctime 几乎是创建时间的对立面。
| 归档时间: |
|
| 查看次数: |
3851 次 |
| 最近记录: |