我试图通过python使用shell命令匹配多行模式。
我可以使用shell命令进行匹配,但是我无法通过Python subprocess.call或os.system模块传递此命令。
我的文件看起来像这样:
(CELL
(CELLTYPE "NAND_2X1")
(INSTANCE U2)
(DELAY
(ABSOLUTE
(IOPATH A1 ZN (0.02700::0.02700) (0.01012::0.01012))
(IOPATH A2 ZN (0.02944::0.02944) (0.00930::0.00930))
)
)
)
不,我想提取这个:
(INSTANCE U2)
(DELAY
(ABSOLUTE
(IOPATH A1 ZN (0.02700::0.02700) (0.01012::0.01012))
(IOPATH A2 ZN (0.02944::0.02944) (0.00930::0.00930))
)
)
使用此正则表达式:
pcregrep -M -n 'INSTANCE U2((?!^\)).*\n)+' sdf/c1_syn_buf2.sdf
其中U2是搜索字符串,sdf / c1_syn_buf2.sdf是文件名
在Python中,我已经定义了一个函数,我将传递搜索字符串和文件名,因为我必须多次执行此操作。
我无法使用以下内容成功执行此命令:
>>>b = subprocess.call(['pcregrep','-M','-n','INSTANCE '+arg, '\)((?!^\).*\n)+ '+file ])
pcregrep: Failed to open \)((?!^\).*
)+ /home/sanjay/thesis/code/sdf/c7552_syn_buf0.sdf: No such file or directory
当我实际输入参数(在本例中为U2)名称和文件名时,我能够获得所需的输出。
修改 如果pcregrep不够友好,这里是awk命令:
awk '/INSTANCE U2/,/^)\n?/' sdf/c1_syn_buf2.sdf
返回相同的内容。
有人可以帮帮我吗?
答案 0 :(得分:1)
只是查看原始命令行,并将调用格式化为每行一个arg,不应该是这样吗?
b = subprocess.call(
['pcregrep',
'-M',
'-n',
'INSTANCE {}\)((?!^\)).*\n)+ '.format(arg),
file ])
我对括号和反斜杠不太确定。这些在正则表达式中总是有点棘手。您可能需要稍微调整它们以获得您想要的内容(在python文档中查看r''正则表达式字符串类型)
答案 1 :(得分:1)
看起来我需要使用格式说明符%s
我使用时可以使用:
b = subprocess.check_output("pcregrep -M -n 'INSTANCE '%s'((?!^\)).*\n)+' {} ".format(file) %arg,shell=True)
有了这个,我得到了变量b
我使用%s传递参数,使用{} .format
方法
答案 2 :(得分:1)
运行shell命令:
$ pcregrep -M -n 'INSTANCE U2((?!^\)).*\n)+' sdf/c1_syn_buf2.sdf
Python中的:
from subprocess import check_output as qx
output = qx(['pcregrep', '-M', '-n', r'INSTANCE {}((?!^\)).*\n)+'.format(arg),
path_to_sdf])
r''
字面值或双倍所有反斜杠此外,您不需要pcregrep
,您可以在Python中搜索文件:
import re
from mmap import ACCESS_READ, mmap
with open(path_to_sdf) as f, mmap(f.fileno(), 0, access=ACCESS_READ) as s:
# arg = re.escape(arg) # call it if you want to match arg verbatim
output = re.findall(r'INSTANCE {}((?!^\)).*\n)+'.format(arg).encode(), s,
flags=re.DOTALL | re.MULTILINE)
mmap
用于容纳不适合内存的文件。它也可能在Windows上运行得更快。