2012-05-19 1 views
20

Ich bin nach einer Möglichkeit, Batch-Dateien umbenennen mit einem regex dhRegex zu Batch-Umbenennen von Dateien in OS X Terminal

s/123/onetwothree/g 

Ich erinnere mich, ich awk und sed mit einem regulären Ausdruck verwenden können, aber konnte nicht herausfinden, wie pipe sie zusammen für die gewünschte Ausgabe.

+0

Ich wollte nur ccpizza danken, da das Python-Regex-Skript für mich großartig funktionierte. Ich hätte aufgestanden, aber ich bin ein Noob, also kann nicht ... kann nicht viel ... kann nicht einmal kommentieren. Ich benutzte sein Python-Skript auf meinem MacBook Pro, um eine Ladung von Dateien mit Erfassungsgruppen umzubenennen, sodass ich keine wichtigen Informationen verlor und die Dateinamen in ein akzeptableres Format umwandeln konnte. Ich beginne gerade erst mit Python, aber liebe Regex und dieses Skript hat gut für mich funktioniert! – NutSoft

Antwort

19

Ein effizienter Weg, um den Umbenennungsvorgang auszuführen ist, um die Umbenennungs Befehle in einer Pipeline Sed und führen sie in den Mantel zu konstruieren.

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

Das \ 2 nach onetwothree sollte sein \ 3 – Cong

+0

Das einzige, was rekursiv funktioniert (mit dem Befehl 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

Sie können Perl-basierte Umbenennungs Dienstprogramm installieren:

brew install rename 

und als es gerade wie verwenden:

rename 's/123/onetwothree/g' * 

, wenn Sie Ihre regex testen möchten, ohne Dateien einfach zu umbenennen add -n switch

1

Ich nehme eine freundliche rekursive Regex-Dateiname Renamer, die standardmäßig nur emula testet den Ersatz und zeigt an, wie die resultierenden Dateinamen lauten würden.

Verwenden Sie -w, um Änderungen tatsächlich zu schreiben, wenn Sie mit dem Ergebnis des Trockenlaufs -s zufrieden sind, um die Anzeige nicht übereinstimmender Dateien zu unterdrücken; -h oder --help zeigt Verwendungshinweise.

Simplest Nutzung:

# 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 

Passende Gruppen (zB \1, \2 usw.) sind ebenfalls unterstützt:

# 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 

Hinweis: vergessen Sie nicht, -w hinzufügen, wenn Sie die getestet Ergebnisse und möchte die Änderungen tatsächlich schreiben.

Funktioniert sowohl mit Python 2.x als auch mit 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)