我正在努力完成以下任务(我一直在寻找答案)。
搜索START_PATTERN和END_PATTERN1之间的文本
拥有如下结构的文件:
text
text
...
START_PATTERN
line1
line2
END_PATTERN2
text
text
...
START_PATTERN
line1
line2
END_PATTERN1
text
text
...
如果找到END_PATTERN2,任务将是重新开始搜索。因此命令输出应为:
START_PATTERN
line1
line2
END_PATTERN1
感谢您的时间!
答案 0 :(得分:2)
此行适用于您的示例:
tac file|sed '/END_PATTERN1/,/START_PAT/!d'|tac
测试:(我将xx
添加到预期的块行中):
kent$ cat f
text
text
...
START_PATTERN
line1
line2
END_PATTERN2
text
text
...
START_PATTERN
xxline1
xxline2
END_PATTERN1
text
kent$ tac f|sed '/END_PATTERN1/,/START_PAT/!d'|tac
START_PATTERN
xxline1
xxline2
END_PATTERN1
只接受第一场比赛,仅限awk:
awk '{a[NR]=$0}
/START_PAT/{s=NR}
/END_PATTERN2/{s=0}
/END_PATTERN1/{exit}
END{for(i=s;i<=NR;i++)print a[i]}' file
答案 1 :(得分:0)
通过在找到第一个模式后保留缓冲线并在找到END_PATTERN2
后重置它来解决此问题:
awk 'x { next }
/START_PATTERN/ { n = 1; f = 1 }
f { lines[n++] = $0 }
/END_PATTERN1/ { f = 0; x = 1 }
/END_PATTERN2/ { n = 1; f = 0 }
END { for (i = 1; i < n; ++i) print lines[i] }' file
f
是一个标志,用于确定是否将当前行保存到缓冲区lines
。 n
是用于索引缓冲区的计数器。处理完文件后,将打印缓冲区中的第一行n
行。
我还添加了一个变量x
,一旦设置,就会跳过所有行。这意味着只保存第一个匹配的块。
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed -n '/START_PATTERN/!d;:a;N;/END_PATTERN2/d;/END_PATTERN1/!ba;p;d' file
使用-n
类似grep的开关。开始收集查找START_PATTERN
的行。如果找到END_PATTERN2
,请删除该集合。找到END_PATTERN1
打印线条。