Mac OS X批量重命名文件(2种模式)

时间:2018-05-09 11:44:36

标签: ruby regex macos terminal batch-rename

我想匹配\d\dQ\d模式或\dQ\d\d模式,并在文件名前重新格式化。使用OSX终端或ruby,最好的方法是什么?它有点复杂,因为它是模式1或模式2。

在第一个文件中,模式“3Q17”是指2017年第3季度的日期。我需要在文件名前面添加2017Q3。但是,我有另一种模式“05Q1”,这意味着2005年第一季度,所以我需要添加2005Q1。

文件:

ABC-EDFGH-JLG-Sample-3Q17-fIS.pdf 
                     ^^^^
2Q13 ABC MF PM Example_fIS.pdf
^^^^
03Q1_FIS.pdf 
^^^^
05Q1 ABC_IS.pdf
^^^^

重命名的文件:

2017Q3_ABC-EDFGH-JLG-Sample-3Q17-fIS.pdf
2013Q2_2Q13 ABC MF PM Example_fIS.pdf
2003Q1_03Q1_FIS.pdf
2005Q1_05Q1 ABC_IS.pdf

这个问题有助于单一模式,但不是2种模式。

mac os x terminal batch rename

我的ruby代码工作正常:

Dir.glob("*.pdf").each do |orig_name|
    new_name = orig_name.gsub(/^.*?(?:(\d\d)Q(\d)|(\d)Q(\d\d))/, '20\1\4Q\2\3_\0')
    File.rename(orig_name, new_name)
end

但是,终端中的重命名脚本(使用brew install rename)提供了错误的结果。

rename -n -e 's/^.*?(?:(\d\d)Q(\d)|(\d)Q(\d\d))/'20\1\4Q\2\3_\0'/' *.pdf
'03Q1_FIS.pdf' would be renamed to '2014Q23_0_FIS.pdf'
'03Q1_vIS.pdf' would be renamed to '2014Q23_0_vIS.pdf'
'05Q1 ABC_IS.pdf' would be renamed to '2014Q23_0 ABC_IS.pdf'
'2Q13 ABC MF PM Example_fIS.pdf' would be renamed to '2014Q23_0 ABC MF PM Example_fIS.pdf'

1 个答案:

答案 0 :(得分:1)

更新

rename使用正则表达式的Perl语法。在Perl之后,它期望反向引用引用捕获的组,否则显示警告。使用Perl正则表达式可以使用branch reset构造(?|(...)|(...)|...)positive lookbehind来解决此问题:

^.*?(?|(\d\d)Q(\d)|Q(\d\d)(?<=(\d)...))

替换为20$1Q$2_$&

正则表达式细分:

  • ^匹配输入字符串的开头
  • .*?将所有事情(不贪婪地)与......相匹配。
  • (?|启动分支重置构造
    • (\d\d)在第1组中捕获两位数字
    • Q匹配Q
    • (\d)捕获第2组中的数字
    • |
    • Q匹配Q
    • (\d\d)在第1组中捕获两位数字
    • (?<=(\d)...)捕获第2组Q之前的数字
  • )构造结束

这样两个捕获组同时存在,第一个捕获组总是指2个数字,第二个是1到1个数字,我们不需要处理4个不同的捕获组。

您可以尝试匹配以pattern开头的两个模式以及开头的更多数字,然后使用一个替换字符串,其中包括对所有捕获组的后向引用。这是正则表达式:

^.*?(?:(\d\d)Q(\d)|(\d)Q(\d\d))

和替换字符串:

20\1\4Q\2\3_\0

Ruby(Live demo

str.gsub(/^.*?(?:(\d\d)Q(\d)|(\d)Q(\d\d))/, '20\1\4Q\2\3_\0')