【问题标题】:Issue with special characters in Python subprocessPython子进程中的特殊字符问题
【发布时间】:2015-10-06 18:00:20
【问题描述】:

我翻译了这个 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;prec=$0;next} pno && !(/^I/ && NR==pno+1){print 前; pno=0} 1' awk: ^ 表达式中的无效字符 '''

示例输入文件:

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

【问题讨论】:

  • 对于这种字符串,使用原始字符串表示法:r"abc\def"。它可以防止错误,并会降低理解您所写内容的整体复杂性。

标签: python awk subprocess


【解决方案1】:

我敢打赌,您的字符串转换存在问题。 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)

【讨论】:

  • 开头和结尾的单引号' 不是实际字符串的一部分,bash 会删除它们。您也必须删除它们。
  • 我需要单引号。如果是原始文字,为什么要删除它们?
  • @Bob:它们不是字符串的一部分。不要混淆文字和相应的字符串对象:内存中没有原始字符串——原始字符串文字只是在 Python 源代码中指定字符串的一种表示法。
  • 嗯,我需要单引号,这是 awk 的正则表达式
  • @Bob: 如果在 shell 中调用 awk 也看不到单引号 -- shell 会去掉引号。
猜你喜欢
  • 2018-03-10
  • 1970-01-01
  • 2018-07-28
  • 2011-04-19
  • 1970-01-01
相关资源
最近更新 更多