如何使用glob / regex模式在终端中重命名文件?

时间:2019-06-26 18:28:47

标签: regex bash terminal glob

我正在尝试创建一种快速的方法来更改文件名格式以重新排列原始文件名。 示例:

我有三个文件:

2019_12_10_Mike_Smith_item1.jpg
2016_06_24_John_Ward_item2.jpg
2011_11_18_Charlie_Coyle_item3.jpg

这三个文件的文件格式为:

YYYY_MM_DD_Fname_Lname_item#.jpg

我想使用以下格式重命名该文件:

Fname_Lname_item#_YYYY_MM_DD.jpg

这样我们的第一个文件将是:

Mike_Smith_item1_2019_12_10.jpg

我在Terminal / Bash上工作的经验很少,并且花了最后几个小时寻找使用GLOB / REGEX的方法。我对正则表达式很熟悉,但是似乎无法弄清楚如何引用分组的项目。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:3)

这是一种使用glob和bash的前缀/后缀删除功能的方法:

for f in *.jpg; do
    g=${f%.jpg}
    mv -i -- "$f" "${g#*_*_*_}_${g%_${g#*_*_*_}}.jpg"
done

示例

考虑包含以下文件的目录:

$ ls *jpg
2011_11_18_Charlie_Coyle_item3.jpg  2016_06_24_John_Ward_item2.jpg  2019_12_10_Mike_Smith_item1.jpg

现在,运行我们的命令:

$ for f in *.jpg; do g=${f%.jpg}; mv -i -- "$f" "${g#*_*_*_}_${g%_${g#*_*_*_}}.jpg"; done

这些是以下文件:

$ ls *jpg
Charlie_Coyle_item3_2011_11_18.jpg  John_Ward_item2_2016_06_24.jpg  Mike_Smith_item1_2019_12_10.jpg

工作原理

  • for f in *.jpg; do

    这将启动当前目录中每个jpg文件的循环。

  • g=${f%.jpg}

    这将从文件名的末尾删除.jpg,并将结果分配给变量g

  • mv -i -- "$f" "${g#*_*_*_}_${g%_${g#*_*_*_}}.jpg"

    这会将文件$f重命名为${g#*_*_*_}_${g%_${g#*_*_*_}}.jpg${g#*_*_*_}是删除日期后的文件名。 ${g%_${g#*_*_*_}}是日期。

    这里是一个示例,显示了逐步发生的情况。首先,为变量f分配文件名:

    $ f=2011_11_18_Charlie_Coyle_item3.jpg
    

    g将是不带后缀的文件名:

    $ g=${f%.jpg}
    

    不带日期的文件名为:

    $ echo "${g#*_*_*_}"
    Charlie_Coyle_item3
    

    不含其余文件名的日期为:

    $ echo "${g%_${g#*_*_*_}}"
    2011_11_18
    
  • done

    这表明循环结束。