通过多行在两个正则表达式模式之间输出文本

时间:2019-02-10 05:09:03

标签: python awk sed grep

如果将myfile带到python可用的环境中,我可以运行以下命令:

cat myfile | python filter.py

filter.py

import sys

results = []
for line in sys.stdin:
    results.append(line.rstrip("\n\r")) 

start_match = "some text"
lines_to_include_before_start_match = 4
end_match = "some other text"
lines_to_include_after_end_match = 4

for line_number, line in enumerate(results):
    if start_match in line:
        for x in xrange(line_number-lines_to_include_before_start_match, line_number):
            print results[x]

        print line

        for x in xrange(line_number+1, len(results)):       
            if end_match in results[x]:
                print results[x]

                for z in xrange(x+1, x+lines_to_include_after_end_match):
                    print results[z]

                break
            else:
                print results[x]

        print ""

但是我要在其中运行的环境没有python。我是否唯一选择将其转换为perl(我知道环境中存在)?有简单的sed或awk命令来执行此操作吗?

我尝试了以下操作,但由于缺少+/- 4行,因此它并不能完全满足我的要求:

cat myfile | sed -n '/some text/,/some other text/p'

[编辑:Python脚本显示lines_to_include_after_end_match为4,但实际上返回3]

3 个答案:

答案 0 :(得分:0)

鉴于行尾为\n,您可以尝试以下操作:

awk '/some text/{if(l4)printf l4;p=5} /some other text/{e=1} e && p {p--; if (!p) {e=0;l4="";}} !p && !e { l4 = l4 $0 "\n"; sub(/[^\n]*\n(([^\n]*\n){4})/,"\1",l4);} p' file

请注意,如果要在结束比赛后再打印4行,标记必须为6。
我认为您自己的python代码在结束比赛后只会再打印3行。

在几行中添加可重复性:

awk '/some text/{if(l4)printf l4;p=5} 
    /some other text/{e=1} 
    e && p {p--; if (!p) {e=0;l4="";}} 
    !p && !e { l4 = l4 $0 "\n"; sub(/[^\n]*\n(([^\n]*\n){4})/,"\1",l4);} 
    p' file

答案 1 :(得分:0)

这可能对您有用(GNU sed):

sed ':a;$!{N;s/\n/&/4;Ta};/1st text/{:b;n;/2nd text/!bb;:c;N;s/\n/&/4;Tc;b};$d;D' file

打开一个包含n行的窗口,如果这些行包含1st text,请打印它们并继续打印直到2nd text,然后再读取m行并进行打印。否则,如果它是文件的末尾,则删除缓冲的行,否则删除缓冲区中的第一行并重复。

如果匹配文本从一​​行的开头或结尾开始,请使用:

sed ':a;$!{N;s/\n/&/4;Ta};/^start/M{:b;n;/end$/M!bb;:c;N;s/\n/&/4;Tc;b};$d;D' file

答案 2 :(得分:0)

使用sed,请尝试:

sed -n "$(($(sed -n '/some text/=' myfile) - 4)),$(($(sed -n '/some other text/=' myfile) + 4))p" myfile
  • 命令sed -n '/some text/='返回与some text相匹配的行号。
  • 然后从上面的数字中减去4。
  • 下一部分sed -n '/some other text/='的工作原理类似,并将获得的行号加4。

请注意,脚本会扫描输入文件3次,可能不适用于执行时间至关重要的情况。

[编辑]

如果文件中有多个"some other text",请改用

sed -n "$(($(sed -n '/some text/=' myfile) - 4)),\$p" myfile | sed "/some other text/{N;N;N;q}"