Python子进程中的特殊字符问题

时间:2015-10-06 18:00:20

标签: python awk subprocess

我翻译了这个bash one-liner:

awk '/\]:$/{pno=NR;prec=$0;next} pno && !(/^I/ && NR==pno+1){print prec; pno=0} 1' filename2 > filename1  

进入这个Python代码

with open('filename1', 'w') as f:
    call(['awk', '/\\\]:$/{pno=NR;prec=$0;next} pno && !(/^I/ && NR==pno+1){print prec; pno=0} 1', 'filename2'], stdout=f)  

然而,输出文件是空的,而不是在我使用bash时。

有了这个:

call(['awk', r"'/\]:$/{pno=NR;prec=$0;next} pno && !(/^I/ && NR==pno+1){print prec; pno=0} 1'"], stdout=f)

我得到了

  

awk:'/]:$ / {pno = NR; pr​​ec = $ 0; next} pno&& !(/ ^ I /&& NR == pno + 1){print   PREC; pno = 0} 1'awk:^表达式中的char'''无效

示例输入文件:

Interval: [ some_value some_value1]:
Interval: [ some_value some_value2]:
some text here1 
some text here2
some text here3
some text here4
Interval: [ some_value some_value3]:
Interval: [ some_value some_value4]:
Interval: [ some_value some_value5]:
Interval: [ some_value some_value6]:
some text here5
some text here6
some text here7
some text here8
Interval: [ some_value some_value7]:
Interval: [ some_value some_value8]:

示例输出文件:

Interval: [ some_value some_value2]:
some text here1
some text here2
some text here3
some text here4
Interval: [ some_value some_value6]:
some text here5
some text here6
some text here7
some text here8

1 个答案:

答案 0 :(得分:2)

我打赌你的字符串转换有问题。 Python版本给出:

>>> print('/\\\]:$/{pno=NR;prec=$0;next} pno && !(/^I/ && NR==pno+1){print prec; pno=0} 1')
/\\]:$/{pno=NR;prec=$0;next} pno && !(/^I/ && NR==pno+1){print prec; pno=0} 1

虽然shell版本给出了。

$ echo '/\]:$/{pno=NR;prec=$0;next} pno && !(/^I/ && NR==pno+1){print prec; pno=0} 1'
/\]:$/{pno=NR;prec=$0;next} pno && !(/^I/ && NR==pno+1){print prec; pno=0} 1

您可以使用原始字符串表示法简化此类内容:

>>> print(r'/\]:$/{pno=NR;prec=$0;next} pno && !(/^I/ && NR==pno+1){print prec; pno=0} 1')
/\]:$/{pno=NR;prec=$0;next} pno && !(/^I/ && NR==pno+1){print prec; pno=0} 1

来自文档:

  

当存在rR前缀时,仍会使用反斜杠来引用以下字符,但所有反斜杠都保留在字符串中。例如,字符串文字r“\ n”由两个字符组成:反斜杠和小写的“n”。字符串引号可以使用反斜杠进行转义,但反斜杠仍保留在字符串中;例如,r“\”“是一个有效的字符串文字,由两个字符组成:反斜杠和双引号

所以对你的命令:

call(['awk', r'/\]:$/{pno=NR;prec=$0;next} pno && !(/^I/ && NR==pno+1){print prec; pno=0} 1', filename2], stdout=f)