执行bash';pythonshell中的复杂find命令

执行bash';pythonshell中的复杂find命令,python,linux,bash,shell,Python,Linux,Bash,Shell,我是python新手。我试图用python执行一个bash脚本,以提取不同文件扩展名的计数。 我尝试了以下命令 import subprocess output = subprocess.check_output("sudo find . -type f -name '*.*' -exec sh -c 'echo ${0##*.}' {} \; | sort | uniq -c | sort -nr | awk '{print $2 ":" $1}'", shell=True) 但是它抛出了一

我是python新手。我试图用python执行一个bash脚本,以提取不同文件扩展名的计数。 我尝试了以下命令

import subprocess
output = subprocess.check_output("sudo find . -type f -name '*.*' -exec sh -c 'echo ${0##*.}' {} \; | sort | uniq -c | sort -nr | awk '{print $2 ":" $1}'", shell=True)
但是它抛出了一个语法错误。 在bashshell中执行find命令

sudo find . -type f -name '*.*' -exec sh -c 'echo ${0##*.}' {} \; | sort | uniq -c | sort -nr | awk '{print $2 ":" $1}'
输出将如下所示

png:3156
json:333
c:282
svg:241
zsh:233
js:192
gz:169
zsh-theme:143
ttf:107
cache:103
md:93
那么,如何在python代码中获得相同的输出呢?在我目前的方法中需要什么样的纠正?
提前感谢

顺便说一句,您可以尝试用纯Python做同样的事情。 下面是实现此功能的最基本代码:

import os

def count_all_ext ( path ):
    res = {}
    for root,dirs,files in os.walk( path ):
        for f in files :
            if '.' in f :
                e = f.rsplit('.',1)[1]
                res[e] = res.setdefault(e,0)+1
    return res.items()


print '\n'.join( '%s:%d'%i for i in count_all_ext('.'))

好的,与Bash代码段相比,它非常长,但它是Python…

顺便说一句,您可以尝试在纯Python中做同样的事情。 下面是实现此功能的最基本代码:

import os

def count_all_ext ( path ):
    res = {}
    for root,dirs,files in os.walk( path ):
        for f in files :
            if '.' in f :
                e = f.rsplit('.',1)[1]
                res[e] = res.setdefault(e,0)+1
    return res.items()


print '\n'.join( '%s:%d'%i for i in count_all_ext('.'))

好的,与Bash代码段相比,它很长,但它是Python…

如注释中所述,字符串中的任何双引号都需要用反斜杠转义:

import subprocess
output = subprocess.check_output("sudo find . -type f -name '*.*' -exec sh -c 'echo ${0##*.}' {} \; | sort | uniq -c | sort -nr | awk '{print $2 \":\" $1}'", shell=True)
双引号字符串中的单引号没有任何特殊含义(除非直接在开头),因此无法避免转义

细节在标题下解释


如评论中所述,另一个可能更容易阅读的选项是使用三重双引号:

import subprocess
output = subprocess.check_output("""sudo find . -type f -name '*.*' -exec sh -c 'echo ${0##*.}' {} \; | sort | uniq -c | sort -nr | awk '{print $2 ":" $1}'""", shell=True)

虽然这回答了这个问题,但为了便于阅读和维护,我建议将其完全替换为Python,正如另一个答案中所建议的那样。

如注释中所述,字符串中的任何双引号都需要用反斜杠转义:

import subprocess
output = subprocess.check_output("sudo find . -type f -name '*.*' -exec sh -c 'echo ${0##*.}' {} \; | sort | uniq -c | sort -nr | awk '{print $2 \":\" $1}'", shell=True)
双引号字符串中的单引号没有任何特殊含义(除非直接在开头),因此无法避免转义

细节在标题下解释


如评论中所述,另一个可能更容易阅读的选项是使用三重双引号:

import subprocess
output = subprocess.check_output("""sudo find . -type f -name '*.*' -exec sh -c 'echo ${0##*.}' {} \; | sort | uniq -c | sort -nr | awk '{print $2 ":" $1}'""", shell=True)


虽然这回答了这个问题,但为了便于阅读和维护,我建议完全用Python替换它,正如另一个答案中所建议的那样。

在外部使用三个引号,如
“sudo…”
awk
部分应该类似于
awk'{print\'{\'$2\:“$1\'}'
。在双引号文件“”中,第1行直接输出=子进程。检查输出(“sudo find.-type f-name.”-exec sh-c'echo${0##*.}{}sort}uniq-c | sort-nr | awk'{print'{2:$1}',shell=True)^SyntaxError:无效语法没有“sudo”该错误是否仍然出现?@GuillaumePaniagua:是没有区别,删除“sudo”后在外部使用三重引号,如
“sudo…”
awk
部分应该类似于
awk'{print\“{\“$2\”:\“$1\”}'
。在双引号文件“”中,第1行直接输出=子进程。检查输出(“sudo find.-type f-name.”-exec sh-c'echo${0##*.}{}sort}uniq-c | sort-nr | awk'{print'{2:$1}',shell=True)^SyntaxError:无效语法没有“sudo”该错误是否仍然发生?@GuillaumePaniagua:是没有区别,删除“sudo”谢谢@Captain'Falm。。。。。希望bash脚本在python中运行!!是的,对不起。。。它比我强,我总是试着用Python编写脚本(而不是依赖于平台的shell),我肯定会认为这是一个更好的方法,而不是拼凑在一起的工具。(澄清“不好”——正确使用,
awk
可以完成
排序
uniq
以及运行参数扩展的shell等工作;使用5个独立的片段而不是一个片段是不知道如何很好地使用该片段的迹象)。@charlesduff感谢您帮助决定正确的方法@船长的弗拉姆:既然bash要求超级用户权限,python方法就可以了!!由于我是python新手,我无法理解以下行:
print'\n'。join(“%s:%d”%i for i in count\u all\u ext('))
请在此处解释join方法!,提前感谢Hanks@Captain'Falm。。。。。希望bash脚本在python中运行!!是的,对不起。。。它比我强,我总是试着用Python编写脚本(而不是依赖于平台的shell),我肯定会认为这是一个更好的方法,而不是拼凑在一起的工具。(澄清“不好”——正确使用,
awk
可以完成
排序
uniq
以及运行参数扩展的shell等工作;使用5个独立的片段而不是一个片段是不知道如何很好地使用该片段的迹象)。@charlesduff感谢您帮助决定正确的方法@船长的弗拉姆:既然bash要求超级用户权限,python方法就可以了!!由于我是python新手,我无法理解以下行:
print'\n'。join(“%s:%d”%i for i in count\u all\u ext('))
请在此处解释join方法!,提前谢谢你太棒了!!你太棒了!!