grep:如何查找表达式

时间:2016-03-17 15:30:01

标签: regex sed grep

我们有一个巨大的文件(数字),我们希望获得两个表达式之间的所有行,例如,

232445 -9998.01 xxxxxxxxxx

234566 -9998.02 xxxxxxxxx

.

.

324444 -8000.012 xxxxxxx

344444 -8000.0 xxxx

表达式为-9998.01-8000.0,因此尝试了:

$ grep -A100000 '[0-9] -9998.[0-9]' mf.in | grep -B100000 '[0-9] -8000.[0-9]' mf.in > mfile.out

这没关系......两者之间的所有线路都得到它......当然,100000是如此之大,以至于保持所有线路......但如果我们错了?即,如果之间有超过100000?在A和B之后我们如何在没有数字规范的情况下取得所有...

PD:我无法使用类似的#34; [...]"表达式

PD2:列有更多数字(此处只有4列)

-1931076.0 -9998.96235 1.0002741998076021 0.0191476198569163

-1931075.0 -9998.95962 1.0000742544770280 0.0192495084654059

-1931074.0 -9998.95688 0.9998778097258081 0.0193725608470694

3 个答案:

答案 0 :(得分:2)

使用awk

awk '$2 ~ /^-9998.01$/{p=1} p{print} $2 ~ /^-8000.0$/{p=0}' file

<强>测试

$ cat file 
232445 -9998.00 xxxxxxxxxx
232445 -9998.01 xxxxxxxxxx
234566 -9998.02 xxxxxxxxx
234566 -9998.03 xxxxxxxxx
234566 -9998.05 xxxxxxxxx
....
....
324444 -8000.011 xxxxxxx
324444 -8000.012 xxxxxxx
344444 -8000.0 xxxx
344444 -8000.1 xxxx

$ awk '$2 ~ /^-9998.01$/{p=1} p{print} $2 ~ /^-8000.0$/{p=0}' file 
232445 -9998.01 xxxxxxxxxx
234566 -9998.02 xxxxxxxxx
234566 -9998.03 xxxxxxxxx
234566 -9998.05 xxxxxxxxx
....
....
324444 -8000.011 xxxxxxx
324444 -8000.012 xxxxxxx
344444 -8000.0 xxxx

答案 1 :(得分:1)

那么它可能不是最好的答案,但是你的命令的简单修复就是使用文件的行数作为-A-B的参数,所以你确定你不能错过任何一行:

NB_LINES=$(wc -l main.c | awk '{print $1}')
grep -A$NB_LINES '[0-9] -9998.[0-9]' mf.in | grep -B$NB_LINES '[0-9] -8000.[0-9]' mf.in > mfile.out

尽管如此,在纯粹的外壳中,我很可能会做类似的事情。或者我会写一个小的python脚本,看起来像:

import re
LINE_RE = re.compile(r'[^ ]+ (-[0-9]+\.[0-9]+) .*')
with open('mf.in', 'r') as fin:
    with open('mf.out', 'w') as fout:
        for line in f:
            match = LINE_RE.match(line)
            if match:
                if float(match.groups()[0]) > -9998.0:
                    fout.write(line)
                elif float(match.groups()[0]) < -8000.0:
                    break

N.B。:这个脚本只是为了揭示算法的想法,盲目编码和未经测试,可能需要进行一些调整才能实际工作

HTH

答案 2 :(得分:1)

sed已使用此表达式内置此功能:

/regex1/,/regex2/ p =&gt; p命令打印2行之间存在的所有行(包含regex1的起始行和包含regex2的结束行(包括输出中的所有行) ))。

以下是您的文件格式示例:

$ cat file
124235 -69768.77 xxx
232445 -9998.01 xxxxxxxxxx
234566 -9998.02 xxxxxxxxx
12345 -124.66 xxxx
324444 -8000.012 xxxxxxx
344444 -8000.0 xxxx
344444 -7000.0 xxxx

$ sed -nr '/^[0-9]+\s-9998.[0-9]+\s/,/^[0-9]+\s-8000.[0-9]+\s/ p' file
232445 -9998.01 xxxxxxxxxx
234566 -9998.02 xxxxxxxxx
12345 -124.66 xxxx
324444 -8000.012 xxxxxxx
344444 -8000.0 xxxx
$