创建文本过滤器的最简单方法是什么,该过滤器仅输出由两个预定义标记包围的文本。我不介意使用任何标准工具:sed,awk,python,...
例如,我想只显示“Mark Begin”和“Mark End”包围的文字。
input:
Text 1
Mark Begin
Text 2
Mark End
Text 3
Mark Begin
Text 4
MarK End
Text 4
output:
Text 2
Text 4
如何修改解决方案,以便只将最后一次出现写入输出,因此对于上面的相同输入,我们得到:
output:
Text 4
答案 0 :(得分:3)
$ awk '/Mark End/{f=0}/Mark Begin/{f=1;next}f' file
Text 2
Text 4
$ awk '/Mark End/{f=0}/Mark Begin/{f=1;next}f{p=$0}END{print p}' file
Text 4
答案 1 :(得分:1)
第1部分
awk '
tolower($0) ~ /mark begin/ {printing = 1; next}
tolower($0) ~ /mark end/ {printing = 0; next}
printing {print}
'
第2部分
awk '
tolower($0) ~ /mark begin/ {capturing = 1; text = ""; next}
tolower($0) ~ /mark end/ {capturing = 0; sep = ""; next}
capturing {text = text sep $0; sep = "\n"}
END {print text}
'
答案 2 :(得分:0)
使用Python和延迟生成器的功能(无状态)实现:
import itertools
def get_lines_between_marks(ilines, start_mark, end_mark):
for line in ilines:
if line.strip().lower() == start_mark:
yield list(itertools.takewhile(lambda s: s.strip().lower() != end_mark, ilines))
for group in get_lines_between_marks(open("file.txt"), "mark begin", "mark end"):
for line in group:
print line,
# Text 2
# Text 4
现在你的第二个要求是微不足道的(见iterlast here):
def iterlast(it):
return reduce(lambda x, y: y, it)
for line in iterlast(get_lines_between_marks(open("file.txt"), "mark begin", "mark end")):
print line,
# Text 4
答案 3 :(得分:0)
输出每个:
sed -n '/^Mark Begin$/{:a;n;/^Mark End$/b;p;ba}' inputfile
输出最后一个
sed -n '${x;s/\n//;p};/^Mark Begin$/{x;s/.*//;x;:a;n;/^Mark End$/b;H;ba}'
答案 4 :(得分:0)
我找到了一个很好的解决方案:
awk '/Mark End/, /Mark Begin/' file.lst
对于第二种情况,但毕竟需要标记过滤。