В Perl есть прекрасная маленькая утилита, которая называется find2perl , которая преобразует (весьма точно) командную строку для утилиты Unix find
в сценарий Perl, который делает то же самое.
Если у вас есть команда 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 сделает то же самое.Затем вы можете изменить сценарий по своему усмотрению.
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 () считает ссылки как файлы;найти пропускает это.
Таким образом, правильная реализация, аналогичная 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.