2012-05-19 52 views
20

我的方式來一批又用正則表達式,即正則表達式來批量重命名的OS X的終端文件

s/123/onetwothree/g 

我記得我可以用awk重命名文件,並用正則表達式的sed但不可能弄清楚如何將它們一起管理以獲得所需的輸出。

+0

我只是想感謝ccpizza,因爲Python正則表達式腳本對我很好。我會upvoted,但我是一個noob所以不能...做不了多少...甚至不能評論。 我在我的MacBook Pro上使用了他的Python腳本來重命名帶有捕獲組的文件,因此我沒有丟失任何重要信息,並且能夠將文件名轉換爲更可接受的格式。 我只是剛剛開始使用Python,但愛正則表達式,這個腳本對我很好! – NutSoft

回答

19

執行重命名操作的一種有效方法是在sed管道中構建重命名命令並將它們饋送到shell中。

ls | 
sed -n 's/\(.*\)\(123\)\(.*\)/mv "\1\2\3" "\1onetwothree\2"/p' | 
sh 
+0

onetwothree之後的\ 2應該是\ 3 – Cong

+0

遞歸(使用find命令)'$ find「的唯一工作。 -iname test * | sed -E's /..//(test)(。*)(\。jpg)/ mv \ 1 \ 2 \ 3 \ 1 \ 214 \ 3 /'| sh' – Binarian

3
for f in $files; do 
    newname=`echo "$f" | sed 's/123/onetwothree/g'` 
    mv "$f" "$newname" 
done 
52

您可以安裝基於Perl重命名工具:

brew install rename 

,並不僅僅是使用它像:

rename 's/123/onetwothree/g' * 

,如果你想測試你的正則表達式,而不只是重命名的文件添加-n開關

1

我採取了友好的遞歸正則表達式文件名重命名,默認情況下只有emula測試替換並顯示結果文件名稱。

使用-w實際編寫的變化你滿意的空運行結果時,-s打壓顯示不匹配的文件; -h--help將顯示使用說明。

簡單的用法:

# replace all occurences of 'foo' with 'bar' 
# "foo-foo.txt" >> "bar-bar.txt" 
ren.py . 'foo' 'bar' -s 

# only replace 'foo' at the beginning of the filename 
# "foo-foo.txt" >> "bar-foo.txt" 
ren.py . '^foo' 'bar' -s 

匹配的組(如\1\2等)的支持太:

# rename "spam.txt" to "spam.py" 
ren.py . '(.+)\.txt' '\1.py' -s 

# rename "12-lovely-spam.txt" to "lovely-spam-12.txt" 
# (assuming two digits at the beginning and a 3 character extension 
ren.py . '^(\d{2})-(.+)\.(.{3})' '\2-\1.\3' -s 

注意:不要忘記添加-w當你測試結果並希望實際編寫更改。

與Python 2.x和Python 3.x一起使用。

#!/usr/bin/python 
# -*- coding: utf-8 -*- 
from __future__ import print_function 
import argparse 
import os 
import fnmatch 
import sys 
import shutil 
import re 


def rename_files(args): 

    pattern_old = re.compile(args.search_for) 

    for path, dirs, files in os.walk(os.path.abspath(args.root_folder)): 

     for filename in fnmatch.filter(files, "*.*"): 

      if pattern_old.findall(filename): 
       new_name = pattern_old.sub(args.replace_with, filename) 

       filepath_old = os.path.join(path, filename) 
       filepath_new = os.path.join(path, new_name) 

       if not new_name: 
        print('Replacement regex {} returns empty value! Skipping'.format(args.replace_with)) 
        continue 

       print(new_name) 

       if args.write_changes: 
        shutil.move(filepath_old, filepath_new) 
      else: 
       if not args.suppress_non_matching: 
        print('Name [{}] does not match search regex [{}]'.format(filename, args.search_for)) 


if __name__ == '__main__': 

    parser = argparse.ArgumentParser(description='Recursive file name renaming with regex support') 

    parser.add_argument('root_folder', 
         help='Top folder for the replacement operation', 
         nargs='?', 
         action='store', 
         default='.') 
    parser.add_argument('search_for', 
         help='string to search for', 
         action='store') 
    parser.add_argument('replace_with', 
         help='string to replace with', 
         action='store') 
    parser.add_argument('-w', '--write-changes', 
         action='store_true', 
         help='Write changes to files (otherwise just simulate the operation)', 
         default=False) 
    parser.add_argument('-s', '--suppress-non-matching', 
         action='store_true', 
         help='Hide files that do not match', 
         default=False) 

    args = parser.parse_args(sys.argv[1:]) 

    print(args) 
    rename_files(args)