Sed一个衬里不能在python子进程中工作

时间:2017-04-13 19:31:10

标签: python json shell sed subprocess

我正在尝试合并此sed命令以删除子文件中的最后一个逗号。

sed -i -e '1h;1!H;$!d;${s/.*//;x};s/\(.*\),/\1 /' file.json"

当我在命令行中运行它时,它工作正常。当我尝试作为子流程运行时,它不起作用。

   Popen("sed -e '1h;1!H;$!d;${s/.*//;x};s/\(.*\),/\1 /' file.json",shell=True).wait()

我做错了什么?

2 个答案:

答案 0 :(得分:1)

它不起作用,因为当你写\1时,python将其解释为\x01而我们的正则表达式不起作用/是非法的。

这已经更好了:

check_call(["sed","-i","-e",r"1h;1!H;$!d;${s/.*//;x};s/\(.*\),/\1 /","file.json"])

因为拆分为真实列表并将正则表达式作为 raw 字符串传递,所以有更好的工作机会。而check_call就是你需要调用一个进程而不需要关心它的输出。

但是我会做得更好:因为python擅长处理文件,考虑到你的相当简单的问题,我会创建一个完全可移植的版本,不需要sed

# read the file
with open("file.json") as f:
   contents = f.read().rstrip().rstrip(",")  # strip last newline/space then strip last comma
# write back the file
with open("file.json","w") as f:
   f.write(contents)

答案 1 :(得分:0)

通常,您可以尝试以下解决方案:

  1. 传递原始字符串,如上所述
  2. 逃离' \'字符。
  3. 此代码也可以满足您的需求:

    Popen("sed -e '1h;1!H;$!d;${s/.*//;x};s/\(.*\),/\\1 /' file.json", shell=True).wait()
    

    try:
        check_call(["sed", "-i", "-e", "1h;1!H;$!d;${s/.*//;x};s/\(.*\),/\\1 /", "file.json"])
    except:
        pass # or handle the error