Python-эквивалент find2perl

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 () считает ссылки как файлы; find пропускает их.

Итак, правильная реализация, аналогичная файлу . -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 и различных побочных эффектов, проверка каждого варианта занимает много времени. Поскольку find является золотым стандартом в мире POSIX по подсчету файлов в дереве, для меня важно делать то же самое в Python.

Так есть ли эквивалент find2perl , который можно использовать для Python? До сих пор я просто использовал find2perl , а затем вручную переводил код Perl.Это сложно, потому что операторы тестирования файлов Perl временами отличаются от файловых тестов Python в os.path.

14
задан dawg 24 September 2011 в 21:39
поделиться