如何在Python子进程中正确转义特殊字符?

3

我正在尝试使用Python子进程运行这个Bash命令

find /Users/johndoe/sandbox -iname "*.py" | awk -F'/' '{ print $NF}'

输出:-

helld.xl.py
parse_maillog.py
replace_pattern.py
split_text_match.py
ssh_bad_login.py

这是我用Python2.7的方式所做的,但输出结果中awk命令过滤器无法工作。

>>> p1=subprocess.Popen(["find","/Users/johndoe/sandbox","-iname","*.py"],stdout=subprocess.PIPE)

>>> p2=subprocess.Popen(['awk','-F"/"','" {print $NF} "'],stdin=p1.stdout,stdout=subprocess.PIPE)

>>>p2.communicate()
('/Users/johndoe/sandbox/argparse.py\n/Users/johndoe/sandbox/custom_logic_substitute.py\n/Users/johndoe/sandbox/finditer_html_parse.py\n/Users/johndoe/sandbox/finditer_simple.py\n/Users/johndoe/sandbox/group_regex.py\n/Users/johndoe/sandbox/helo.py\n/Users/johndoe/sandbox/newdir/helld.xl.py\n/Users/johndoe/sandbox/parse_maillog.py\n/Users/johndoe/sandbox/replace_pattern.py\n/Users/johndoe/sandbox/split_text_match.py\n/Users/johndoe/sandbox/ssh_bad_login.py\n', None)

我也可以只使用p1来获取输出,就像下面这样,但是我无法让awk在这里工作。
list1=[]
result=p1.communicate()[0].split("\n")
for item in res:
    a=item.rstrip('/').split('/')
    list1.append(a[-1])
print list1
3个回答

3

当您不调用shell时,您错误地传递了shell引号(以及甚至不需要shell的额外 shell引号!)。 不要这样做。

p2=subprocess.Popen(['awk', '-F/', '{print $NF}'], stdin=...

当你使用shell=True时,你需要在某些参数周围加上额外的引号来保护它们免受shell的影响,但是这里没有shell,因此将它们放入是不正确的,并会导致Awk解析错误。
然而,你几乎永远不需要从Python调用Awk,特别是对于Python可以轻松本地完成的琐碎任务。
list1 = [line.split('/')[-1]
            for line in subprocess.check_output(
                ["find", "/Users/johndoe/sandbox",
                 "-iname", "*.py"]).splitlines()]

在这种情况下,还要注意GNU find已经有一个直接生成此结果的功能:
list1 = subprocess.check_output(
    ["find", "/Users/johndoe/sandbox",
     "-iname", "*.py", "-printf", "%f\\n"]).splitlines()

дҢ йқһеёёе‡ғ色地成功移除дғ†findе‘Ң令иҰЊдё­зљ„еә•еЏ·пәЊж‰Ђд»ӨдёҚжё…жӨљдёғд»Ђд№€дәљзЉҮиү™дёҒй”™иҮҮгЂ‚ - tripleee
1
顺便提一下,还可以参考https://dev59.com/NWkw5IYBdhLWcg3wMHum。 - tripleee

0
如果你不介意使用 shell=True ,那么这应该是一个相当简单的解决方案。
from subprocess import Popen
import subprocess
command='''
find /Users/johndoe/sandbox -iname "*.py" | awk -F'/' '{ print $NF}'
'''
process=Popen(command,shell=True,stdout=subprocess.PIPE)
result=process.communicate()
print result

0
使用这个: p2.communicate()[0].split("\n")
它将输出一个行的列表。

我可以使用它,但我真的想知道如何在这里使用awk,其中涉及到特殊字符,如" , { , }, ' , /等等。 - sherpaurgen
/ 不再比 .a 更加 "特殊"。 - tripleee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接