Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的grep_Python_Bash - Fatal编程技术网

python中的grep

python中的grep,python,bash,Python,Bash,我习惯于用bash编写脚本,但我也在学习python。 因此,作为一种学习方式,我正在尝试用python修改我的几个旧bash。比如说,我有一个文件,行如下: TOTDOS= 0.38384E+02n_Ef= 0.81961E+02 Ebnd 0.86883E+01 要获得bash中TOTDOS的值,我只需执行以下操作: grep "TOTDOS=" 630/out-Dy-eos2|head -c 19|tail -c 11 但通过python,我正在做: #!/usr/bin/python

我习惯于用bash编写脚本,但我也在学习python。 因此,作为一种学习方式,我正在尝试用python修改我的几个旧bash。比如说,我有一个文件,行如下:

TOTDOS= 0.38384E+02n_Ef= 0.81961E+02 Ebnd 0.86883E+01
要获得bash中TOTDOS的值,我只需执行以下操作:

grep "TOTDOS=" 630/out-Dy-eos2|head -c 19|tail -c 11
但通过python,我正在做:

#!/usr/bin/python3
import re
import os.path
import sys

f1 = open("630/out-Dy-eos2", "r")
re1 = r'TOTDOS=\s*(.*)n_Ef=\s*(.*)\sEbnd'
for line in f1:
    match1 = re.search(re1, line)
    if match1:
        TD = (match1.group(1))
f1.close()
print(TD)
这肯定给出了正确的结果,但似乎比BashEx更重要,更不用说正则表达式的问题了


问题是,我是在python中工作过度,还是缺少了一些东西?

与bash行匹配的python脚本更像这样:

with open('630/out-Dy-eos2', 'r') as f1:
    for line in f1:
        if "TOTDOS=" in line:
            print line[8:19]
现在看起来好多了

[…]但似乎不仅仅是bash

生成器可能是与shell中使用的管道过滤最接近的Python概念

import itertools

#
# Simple generator to iterate through a file
# equivalent of line by line reading from an input file
def source(fname):
    with open(fname,"r") as f:
        for l in f:
            yield l


src = source("630/out-Dy-eos2")

# First filter to keep only lines containing the required word
# equivalent to `grep -F`
filter1 = (l for l in src if "TOTDOS=" in l)

# Second filter to keep only line in the required range
# equivalent of `head -n ... | tail -n ...`
filter2 = itertools.islice(filter1, 10, 20,1)


# Finally output
output = "".join(filter2)
print(output)
关于您的具体示例,如果需要,可以在生成器中使用regexp:

re1 = r'TOTDOS=\s*(.*)n_Ef=\s*(.*)\sEbnd'
filter1 = (m.group(1) for m in (re.match(re1, l) for l in src) if m)

这些只是您可以使用的一些基本构建块。

您希望得到什么样的输出?除非您确实需要复杂的模式匹配,否则请使用if子字符串-速度更快,更易于阅读。也就是说,在bash中有一些事情更容易做到:基于行的过滤就是其中之一value@PadraicCunningham如果所有行的格式都相似[x代表行中的x.split if x[-1],则grepit也不会。isdigit]将执行相同的操作