我是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)
但它会引发语法错误。 在bash shell中执行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代码中获得相同的输出?我当前的方法需要什么修正? 提前致谢
答案 0 :(得分:3)
如评论中所述,引用双引号的字符串中的任何双引号都需要使用反斜杠进行转义:
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)
双引号字符串中的单引号没有任何特殊含义(直接在开头除外),因此不允许您避免转义。
详细信息在标题String and Bytes literals from the Python language reference下解释。
如评论中所述,另一个可能更容易阅读的选项是使用三重双引号:
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完全替换它,如另一个答案所示。
答案 1 :(得分:2)
顺便说一句,你可以尝试在纯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 ......