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.