Python - Шаблон "Найти и сделать что-нибудь"
Время от времени возникает необходимость найти все файлы с текущей папки и глубже и проделать какие-либо действия над ними.
Для этого написал шаблон который можно быстро модифицировать под любые нужны:
Исходный код#! /usr/bin/python import os import glob what_to_find = "*" def do_something_with_directory(path, do_nothing=False): # Uncomment this if you need to do something with directories #return do_something(path, do_nothing) return path def do_something(path, do_nothing=False): filepath, filename = os.path.split(path) if do_nothing: print "Do nothing with %s" % (path) return path else: # Replace this string with your code os.system("echo Done something with %s" % (path)) # return path def search(path=".", do_nothing=False): for item in glob.glob(os.path.join(path, what_to_find)): if os.path.isdir(item): search(do_something_with_directory(item, do_nothing), do_nothing) elif os.path.isfile(item): do_something(item, do_nothing) def request_confirmation(text): resplist = { "yes": True, "y": True, "n": False, "no": False } while 1: print "%s [y\\n]:" % (text), choice = raw_input().lower() if choice.strip() in resplist: return resplist[choice.strip()] if __name__ == "__main__": search(do_nothing=True) if request_confirmation("Do something with theese files"): search()
В качестве примера могу привести такой случай:
Установил я у себя CherryMusic, но из за проблемы в CherryPy(Фреймворк на котором основан CherryMusic в последней версии которого неприятный баг, он не хочет работать с кирилическими URL), стал вопрос, либо искать решения с CherryPy(к слову этот баг исправлен в девелоперской ветке), либо переименовать все файлы и папки в транслит.
Выбран был второй вариант решения проблемы, т.к. не люблю кририлицу в именах файлов, модифицировал шаблон выше вот таким образом:
Исходный код#! /usr/bin/python import os import glob import re import trans from collections import Counter what_to_find = "*" regexp = "^[a-zA-Z\_\.0-9]+$" def do_something_with_directory(path, do_nothing=False): return do_something(path, do_nothing) def do_something(path, do_nothing=False): filepath, filename = os.path.split(path) if not re.match(regexp, filename): newfilename = trans.trans(filename.decode("utf8"))[0].replace(" ", "_").encode("utf8") newfilepath = os.path.join(filepath, newfilename) if path != newfilepath: if do_nothing: print "Move %s to %s" % (path, newfilepath) return [True, path] else: if os.path.exists(newfilepath): return [True, path] try: os.rename(path, newfilepath) except: return [False, path] print "Moved %s to %s" % (path, newfilepath) return [True, newfilepath] else: return [False, path] def search(path=".", do_nothing=False): done_count = Counter(counter=0) for item in glob.glob(os.path.join(path, what_to_find)): if os.path.isdir(item): done, dirname = do_something_with_directory(item, do_nothing) if done: done_count['counter'] += 1 done_count += search(dirname, do_nothing) elif os.path.isfile(item): done, newname = do_something(item, do_nothing) if done: done_count['counter'] += 1 return done_count def request_confirmation(text): resplist = { "yes": True, "y": True, "n": False, "no": False } while 1: print "%s [y\\n]:" % (text), choice = raw_input().lower() if choice.strip() in resplist: return resplist[choice.strip()] def main(): count_to_do = search(do_nothing=True)['counter'] if count_to_do and request_confirmation("\nRename files"): items_done = search()['counter'] items_failed = count_to_do - items_done print "Finished, %d items renamed" % items_done if items_failed: print "%d items failed to rename!" % items_failed else: print "Everything is fine, nothing to do." if __name__ == "__main__": main()
Все что делает скрипт это находит файлы с посторонними символами в названии, затем запрашивает разрешение на переименование этих файлов и папок, после этого и переименует их в транслит(используя модуль trans), приводя в конце информацию о проделанной работе.