Perl имеет прекрасную небольшую утилиту под названием find2perl, которая будет (довольно верно) перевести командную строку для утилиты Unix find в Perl script сделать то же самое.
Если у вас есть команда find, выполните следующие действия:
find /usr -xdev -type d -name '*share'
^^^^^^^^^^^^ => name with shell expansion of '*share'
^^^^ => Directory (not a file)
^^^ => Do not go to external file systems
^^^ => the /usr directory (could be multiple directories
Он находит все каталоги, заканчивающиеся на share ниже /usr
Теперь запустите find2perl /usr -xdev -type d -name '*share', и он испустит Perl script, чтобы сделать то же самое. Затем вы можете изменить script на использование.
Python имеет os.walk(), который, безусловно, имеет необходимую функциональность, рекурсивный список каталогов, но есть большие различия.
Возьмите простой случай find . -type f -print, чтобы найти и распечатать все файлы в текущем каталоге. Наивная реализация с использованием os.walk() будет:
for path, dirs, files in os.walk(root):
if files:
for file in files:
print os.path.join(path,file)
Однако это приведет к разным результатам, чем печатать find . -type f -print в оболочке.
Я также тестировал различные циклы os.walk():
# create pipe to 'find' with the commands with arg of 'root'
find_cmd='find %s -type f' % root
args=shlex.split(find_cmd)
p=subprocess.Popen(args,stdout=subprocess.PIPE)
out,err=p.communicate()
out=out.rstrip() # remove terminating \n
for line in out.splitlines()
print line
Разница в том, что os.walk() считает ссылки в виде файлов; find пропускает их.
Итак, правильная реализация, аналогичная file . -type f -print, становится:
for path, dirs, files in os.walk(root):
if files:
for file in files:
p=os.path.join(path,file)
if os.path.isfile(p) and not os.path.islink(p):
print(p)
Поскольку существует сотни перестановок первичных элементов поиска и различных побочных эффектов, это становится трудоемким для тестирования каждого варианта. Поскольку find является золотым стандартом в мире POSIX о том, как подсчитывать файлы в дереве, для меня это важно для Python.
Итак, существует ли эквивалент find2perl, который можно использовать для Python? До сих пор я только что использовал find2perl, а затем вручную перевел код Perl. Это сложно, потому что операторы проверки файлов Perl разные, чем тесты файлов Python в os.path.