python子进程调用的sed转义错误

时间:2018-11-27 23:32:20

标签: python string sed subprocess escaping

我正尝试使用sed如下致电subprocess.check_call

with open(output_file,'w+') as f:
    subprocess.check_call(['sed', r':a;s/^\(\([^"]*,\?\|"[^",]*",\?\)*"[^",]*\),/\1 /;ta s/,$//; s/\.00//g; s/"//g', input_file], stdout = f, shell=True)

但是,我遇到了这样的错误

'\"[^\"' is not recognized as an internal or external command, operable program or batch file. 

命令sed ':a;s/^\(\([^"]*,\?\|"[^",]*",\?\)*"[^",]*\),/\1 /;ta s/,$//; s/\.00//g; s/"//g' input_file > output_file本身在bash中有效,因此我怀疑这是由一些转义问题引起的。

1 个答案:

答案 0 :(得分:1)

当前的问题是您要传递包含;的令牌而没有用shell=True对其进行引用;但由于您已经将命令解析为令牌,因此您不需要或不需要shell=True,因此直接解决方法是将其删除。请参阅Actual meaning of 'shell=True' in subprocess的含义,此处的错误原因以及通常希望避免的原因。

但是,您的sed脚本似乎试图将CSV变成空格分隔,保留了带引号的字段,但删除了所有引号。有一个用于解析CSV的Python库,可能会做得更好。

import csv

with open(inputfile, 'r') as inp, open(output_file, 'w+') as out:
    reader = csv.reader(inp)
    writer = csv.writer(out, delimiter=' ', quoting=csv.QUOTE_NONE)
    for row in reader:
        for k in row:
            row[k] = row[k].replace('.00', '')
         writer.writerow(row)

这是临时性的,可能需要进行一些调整(我可能忽略了您的sed脚本中的一些细节),但应该为您提供一个彻底摆脱subprocess的思路,并且可能会更好地控制脚本的运行方式(以及三个月后有机会了解其内容)。