2012-05-19 5 views
20

Jestem po sposób do partii zmieniać nazwy plików z IE regexRegex do partii zmieniać nazwy plików w OS X Terminal

s/123/onetwothree/g 

wspominam mogę używać awk i sed z regex, ale nie mogliśmy dowiedzieć się, w jaki sposób połącz je ze sobą, aby uzyskać pożądaną moc wyjściową.

+0

Po prostu chciałem podziękować ccpizza, ponieważ skrypt regex Pythona działał doskonale dla mnie. Chciałbym przegłosować, ale jestem noobem, więc nie mogę ... nie mogę zrobić wiele ... nie mogę nawet komentować. Użyłem jego skryptu Python na moim MacBooku Pro, aby zmienić nazwę ładunku plików z grupami przechwytywania, więc nie straciłem żadnych istotnych informacji i mogłem przenieść nazwy plików do bardziej akceptowanego formatu. Dopiero zaczynam od Pythona, ale uwielbiam regex i ten skrypt zadziałał dobrze! – NutSoft

Odpowiedz

19

Efektywny sposób wykonywania operacji zmiany nazwy jest skonstruowanie polecenia nazwa w sed rurociągu i podawania ich na powłoki.

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

\ 2 po onetwothree powinno być \ 3 – Cong

+0

Jedyną rzeczą, która działała rekurencyjnie (za pomocą polecenia find) '$ find. -wprowadzenie testu * | 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

Można zainstalować Perla oparciu narzędzie Zmień nazwę:

brew install rename 

i nie tylko używać go jak:

rename 's/123/onetwothree/g' * 

jeśli chcesz przetestować regex bez zmiany nazwy plików po prostu add -n switch

1

Moje podejście do przyjaznego rekurencyjnego pliku regex do nazwy pliku, który domyślnie tylko emula Zastępuje zamiennik i pokazuje, jakie będą wynikowe nazwy plików.

Użyj -w, aby zapisać zmiany, gdy jesteś zadowolony z rezultatu próbnego, -s, aby wyłączyć wyświetlanie niepasujących plików; -h lub --help wyświetli uwagi o użytkowaniu.

Najprostszy sposób użycia:

# 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 

Dopasowany grupy (np \1\2, etc) są obsługiwane za:

# 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 

UWAGA: Nie zapomnij dodać -w kiedy badano wyniki i chcą faktycznie zapisać zmiany.

Działa zarówno w języku Python 2.x, jak i w języku 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)