使用文件名的现有部分重命名文件的Bash脚本帮助

时间:2015-07-05 04:03:55

标签: bash

我正在寻找有关bash脚本的帮助来为我重命名文件。我对bash脚本的了解不多,而且我读到的内容是压倒性的。对于我可能会遇到的有限应用程序,了解/了解很多。

在Dropbox中,我的媒体文件的名称如下:

  • 照片Jul 04,5 49 44 PM.jpg
  • 视频6月22日,11月21日AM.mov

我希望以下列格式重命名: 2015-07-04 1749.ext

一些困难:

  1. 脚本必须确定AM或PM是否以正确的24小时格式输入
  2. 未指明年份;假设当年是安全的
  3. 日期,分钟和秒都有前导零,但小时没有;因此,小时后的位置不是绝对的
  4. 任何帮助将不胜感激。 FWIW,我正在运行MacOS。

2 个答案:

答案 0 :(得分:1)

虽然不是date的简单解析和重新格式化,但并不困难。 参数扩展/子字符串删除的bash字符串工具是您将日期的各个部分解析为date可用于以使用格式输出新日期字符串的格式所需的全部内容在文件名中。 (参见String Manipulationdate -d用于根据原始文件名的内容生成新的日期字符串。

注意:以下假设Dropbox文件名采用您指定的格式。 (它并不关心名称或扩展名的第一部分是什么,只要它与您指定的格式相匹配)下面是一个正确隔离以指定格式生成日期所需的文件名片段的示例)

此外,所有空格都已从文件名中删除。虽然您最初在白天和小时之间显示了空格,但我不会通过在文件名中插入空格来提供不良练习的示例。因此,空格已替换为'_''-'

#!/bin/bash

# Photo Jul 04, 5 49 44 PM.jpg
# Video Jun 22, 11 21 00 AM.mov

# fn="Photo Jul 04, 5 49 44 PM.jpg"
fn="Video Jun 22, 11 21 00 AM.mov"

ext=${fn##*.}                       # determine extension
prefix=${fn%% *}                    # determine prefix (Photo or Video)
datestr=${fn%.${ext}}               # remove extension from filename
datestr=${datestr#${prefix} }       # remove prefix from datestr
day=${datestr%%,*}                  # isolate Month and date in day
ampm=${datestr##* }                 # isloate AM/PM in ampm
datestr=${datestr% ${ampm}}         # remove ampm from datestr
timestr=${datestr##*, }             # isolate time in timestr
timestr=$(tr ' ' ':' <<<"$timestr") # translate spaces to ':' using herestring
cmb="$day $timestr $hr"             # create combined date/proper format

## create date/time string for filename
datetm=$(date -d "$cmb" '+%Y%m%d-%H%M')

newfn="${prefix}_${datetm}.${ext}"

## example moving of file to new name
#  (assumes you handle the path correctly)
printf "mv '%s' %s\n" "$fn" "$newfn"
#  mv "$fn" "$newfn" # uncomemnt to actually use

exit 0

示例/输出

$ bash dateinfname.sh
mv 'Video Jun 22, 11 21 00 AM.mov' Video_20150622-1121.mov

答案 1 :(得分:1)

Mac OSX

这使用awk重新格式化日期字符串:

for f in *.*
do
    new=$(echo "$f" | awk -F'[ .]' '
    BEGIN {
        split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec",month)
        for (i in month) {
            nums[month[i]]=i
        }
    }
    $(NF-1)=="PM" {$4+=12;}
    {printf "%s 2015-%02i-%02i %02i%02i.%s",$1,nums[$2],$3,$4,$5,$8;}
    ')
    mv "$f" "$new"
done

运行上述命令后,文件名为:

$ ls -1 *.*
Photo 2015-07-04 1749.jpg
Video 2015-06-22 1121.mov

以上是在GNU awk上测试的,但我不相信我已经使用过任何特定于GNU的功能。

的GNU / Linux

GNU date有一个方便的功能来解释人类日期字符串:

for f in *.*
do
    prefix=${f%% *}
    ext=${f##*.}
    datestr=$(date -d "$(echo "$f" | sed 's/[^ ]* //; s/[.].*//; s/ /:/3; s/ /:/3; s/,//')" '+%F %H%M')
    mv "$f" "$prefix $datestr.$ext"
done

以下是操作中脚本的示例:

$ ls -1 *.*
Photo Jul 04, 5 49 44 PM.jpg
Video Jun 22, 11 21 00 AM.mov
$ bash script
$ ls -1 *.*
Photo 2015-07-04 1749.jpg
Video 2015-06-22 1121.mov