我们有一个巨大的文件(数字),我们希望获得两个表达式之间的所有行,例如,
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
答案 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
$