【问题标题】:Mac OS X Rename files in Batch (2 patterns)Mac OS X 批量重命名文件(2 种模式)
【发布时间】:2018-10-19 12:36:47
【问题描述】:

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

在第一个文件中,例如模式“3Q17”是一个日期,表示 2017 年第三季度。我需要在文件名前添加 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

这个问题对单个模式有帮助,但对两个模式没有帮助。

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'

【问题讨论】:

  • 所以您知道解决方案但正在寻找最合适的方法?
  • 我知道一个解决方案,从这里为一个模式,但不是两个
  • 请详细说明预期输出。目前很难捕捉。
  • @revo 以上更新
  • 你试过什么?我们这里的大多数人都很乐意帮助你提高你的手艺,但作为短期无偿编程人员不太乐意。在MCVE 中向我们展示您迄今为止的工作、您期望的结果以及您得到的结果,我们将帮助您解决问题。

标签: ruby regex macos terminal batch-rename


【解决方案1】:

更新

rename 对正则表达式使用 Perl 语法。在 Perl 之后,它期望反向引用引用捕获的组,否则会显示警告。使用 Perl 正则表达式有一个解决方法,使用 branch reset 构造 (?|(...)|(...)|...)positive lookbehind

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

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

正则表达式分解:

  • ^匹配输入字符串的开始
  • .*? 匹配每件事(不贪心)直到...
  • (?| 分支重置构造的开始
    • (\d\d) 捕获组 1 中的两位数
    • Q匹配Q
    • (\d)在第 2 组中捕获一个数字
    • |或者
    • Q 匹配 Q
    • (\d\d) 捕获组 1 中的两位数
    • (?&lt;=(\d)...) 在第 2 组中捕获 Q 前面的数字
  • ) 构造结束

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


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

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

和替换字符串:

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

鲁比 (Live demo)

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

【讨论】:

  • 如果可能,尝试通过重命名来实现,见上文。有什么想法吗?
  • 试试's/^.*?(?:(\d\d)Q(\d)|(\d)Q(\d\d))/20$1$4Q$2$3_$0/'
  • 我试过在 (eval 2) 第 1 行的连接 (.) 或字符串中使用未初始化的值 $4。
  • 我认为如果它找到第一个模式,那么第二个是 nil。所以它出错了
  • @user2012677 看来您无法解决这个问题,但我发现 rename 使用 Perl 正则表达式风格,因此修改了正则表达式以使用 Perl 中可用的功能。试试这个rename -n -e 's/^.*?(?|(\d\d)Q(\d)|Q(\d\d)(?&lt;=(\d)...))/20$1Q$2_$&amp;/' *.pdf
猜你喜欢
  • 2015-09-13
  • 2012-05-26
  • 2016-10-26
  • 1970-01-01
  • 2011-11-05
  • 2017-09-19
  • 2016-07-05
  • 2010-12-12
  • 2013-12-19
相关资源
最近更新 更多