Python相当于find2perl

daw*_*awg 14 python find os.walk

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
Run Code Online (Sandbox Code Playgroud)

它找到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)
Run Code Online (Sandbox Code Playgroud)

但是,这会产生与find . -type f -print在shell中键入不同的结果.

我也一直在测试各种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
Run Code Online (Sandbox Code Playgroud)

区别在于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)
Run Code Online (Sandbox Code Playgroud)

由于有数百种寻找原色和不同副作用的排列,因此测试每种变体都需要耗费时间.既然find是POSIX世界中关于如何计算树中文件的黄金标准,那么在Python中以同样的方式执行它对我来说非常重要.

那么是否find2perl可以使用相同的Python?到目前为止,我刚刚使用find2perl然后手动翻译Perl代码.这很难,因为Perl文件测试操作符有时与os.path中的Python文件测试不同.

the*_*olf 2

有一些观察结果和几段代码可以帮助您。

首先,Python 可以像 Perl 一样执行这种形式的代码:

 cat code.py | python | the rest of the pipe story...
Run Code Online (Sandbox Code Playgroud)

find2perl是一个聪明的代码模板,它基于 find 模板发出 Perl 函数。因此,复制这个模板,您将不会拥有您所感知的“数百种排列”。

其次,结果find2perl并不完美,就像 find 版本(例如 GNU 或 BSD)之间存在潜在差异一样。

第三,默认os.walk是自下而上;find是自上而下的。如果您在递归时底层目录树发生变化,这会产生不同的结果。

Python 中有两个项目可以帮助您:twanderdupfinder。每个都努力独立于操作系统,并且每个都递归文件系统,例如find.

如果您find在 Python 中模板化一个通用的 like 函数,设置os.walk为自上而下递归,使用 glob 来复制 shell 扩展,并使用您在这两个项目中找到的一些代码,那么您可以find2perl毫无困难地进行复制。

抱歉,我无法指出可以满足您需求的东西......