我有一堆 JPEG 文件,每个文件的名称完全相同(即“orig.jpg”),位于单独的子目录中。每个子目录都有一个唯一的名称(例如 xplmz3nc5n、tyrn5m6ktv 等...)。
我想根据 jpeg 的创建日期/时间重命名它们(例如 20120629_142536.jpg 等)。
我能够使用 photoshop 批量重命名每个文件,并赋予其唯一的标识符。实现此功能的关键功能是 photoshop 能够在批处理过程中“包含所有子目录”。我希望能够使用 exiftool 重命名文件,并包含创建日期(以便于编目)。不幸的是,photoshop 批量重命名过程会将文件的创建日期重写为今天的日期...
关于使用终端命令等批量重命名一系列子目录中的文件的方法,有什么建议吗?
编辑
答案这里在终端中得到以下结果
cd ~/foo
for dir in *; do
t=`stat -c %y "$dir" | awk '{print $1"-"$2}' |
cut -d ":" -f 1,2 | sed 's/://'`
mv "$dir" "$t"_"$dir";
done
并得到
stat:非法选项——c 用法:stat [-FlLnqrsx] [-f 格式] [-t timefmt] [文件 ...] stat:非法选项——c 用法:stat [-FlLnqrsx] [-f 格式] [-t timefmt] [文件 ...] stat:非法选项——c 用法:stat [-FlLnqrsx] [-f 格式] [-t timefmt] [文件 ...]
(即我尝试了两种不同的方法......)。
答案1
使用 EXIF 创建日期的一种可能性是(未经测试,但应该可行):
将所有文件移动到同一目录中,并将其重命名为唯一的名称(例如,包含目录的名称加上后缀
.jpg
)cd ~/foo for i in */; do # moves the file (supposedly named orig.jpg) in current directory # renaming it to the name of the containing sub directory mv ${i}orig.jpg ./`basename $i`.jpg # removes the subdirectory, assuming it is now empty rmdir $i; done
.jpg
如果文件命名方式并不总是相同,但子目录中只有一个文件(名称以 结尾),那么您当然可以mv
用以下命令替换该命令:mv ${i}*.jpg ./`basename $i`.jpg
然后使用以下命令重命名它们
exiftool
:exiftool -d %Y%m%d_%H%M%S.jpg "-filename<CreateDate" ~/foo
这假设没有文件在秒级上具有相同的创建时间。如果存在文件名冲突的风险,则可以使用在文件名重复的情况下添加后缀的变体:
exiftool -d %Y%m%d_%H%M%S%-c.jpg "-filename<CreateDate" ~/foo
有关此处重命名功能的更多信息exiftool
:http://www.sno.phy.queensu.ca/~phil/exiftool/filename.html
答案2
不幸的是,OSX 没有 GNU 工具,而是其核心实用程序是 BSD 版本的分支。这意味着您在 Linux 上找到的许多命令行答案都不适用。要么是因为缺少相关选项,要么是因为它们不同。
我没有 OSX 机器来测试这个,但是根据 OSX 手册页stat
和date
,这应该可以满足您的需要:
find . -name orig.jpg |
while read file; do
echo mv "$file" "$(date -jf "$(stat -f '%m' "$file")" +%Y%m%d_%H%M%S)".jpg
done
如果您的目录名称可以包含空格或其他奇怪的字符,请改用以下名称:
find . -name orig.jpg -print0 |
while IFS= read -r -d '' file; do
echo mv "$file" "$(date -jf "$(stat -f '%m' $file)" +%Y%m%d_%H%M%S)".jpg
done
这只会打印将要运行的命令。如果它们正确,请删除echo
并再次运行它以实际重命名文件。正如我所说,我无法测试这一点,因为我无法访问 OSX 计算机,所以您可能需要对其进行调整。请查看我链接到的手册页(或man stat
在您的机器上运行)。我不确定 OSXdate
是否可以处理的输出stat -f '%m'
,如果不能,请告诉我,我会尽力提供帮助。
解释
find . -name orig.jpg
origin.jpg
:递归查找当前文件夹中调用的所有文件。while read file; ... ; do
find
:这将保存as找到的每个文件名$file
,然后对每个文件名运行下一个命令。stat -f '%m' $file
:这应该以人类可读的格式显示文件的修改时间。$(date -jf "DATE" +%Y%m%d_%H%M%S)
:以 YYMMDD_HHMMSS 格式打印 给出的日期DATE
。由于我们给出 的输出stat -f '%m' $file
,因此它将打印文件修改的日期。mv "$file" "$(date -jf "$(stat -f '%m' $file)" +%Y%m%d_%H%M%S)".jpg
:重命名为和$file
返回的日期。date
.jpg
Linux 上的等效命令是:
find . -name orig.jpg |
while read file; do
echo mv "$file" "$(date -d "$(stat -c '%y' $file)" +%Y%m%d_%H%M%S)".jpg
done