我有一个包含数百个段落的文件,每个段落大约 15 行。我需要寻找一种模式,比如说发生次数:1。如果在段落中找到这种模式,我需要打印整个段落。请注意,段落之间由 2 个换行符分隔。
我已经尝试了下面的代码行,这显然打印了文件中的第一个匹配项。我不知何故无法使用循环并打印所有此类事件。
sed -n '1,/Occurrence: 1/p' ystdef.txt | tail -9 > ystalarm.txt
我可以使用g
(全局)标志来sed
完成这项工作吗?如果是,怎么办?
请注意,我知道这些grep -A/B/C
命令,但它们无法在我的 Cygwin 终端上运行。
答案1
您可以使用 awk 的“段落模式”,其中输入记录由至少两个换行符的序列分隔。这是通过设置RS
为空字符串来激活的。
awk -v RS= '/Occurance: 1/' ystdef.txt
请注意,这些段落将全部折叠在一起打印(其内容之间有一个换行符)。 awk 不允许您将输出分隔符与输入分隔符相匹配(某些 GNU awk 扩展除外),但您可以轻松地将段落分隔符标准化为两个换行符。
awk -v RS= -v ORS='\n\n' '/Occurance: 1/' ystdef.txt
如果您不想在末尾添加额外的换行符:
awk -v RS= '/Occurance: 1/ {if (not_first) print ""; print; not_first=1}' ystdef.txt
答案2
这是 GNU 中的sed
:
sed '/./{H;$!d};x;/SEARCH/!d'
可移植/POSIX 语法:
sed -e '/./{H;$!d;}' -e 'x;/SEARCH/!d'
如果一行包含一个或多个字符,则会将其附加到H
旧空格中;如果是!
最后$
一行,则将其删除。这意味着每一个非空白行都会被存储并从输出中删除。
所以如果一条线是不是 d
eleted 然后sed
ex
更改保持和模式空间的内容。这使得保留空间只有一个空行,并且模式空间自最后一个空行以来的所有行。
sed
然后解决模式/SEARCH/
。如果!
没有找到,它将 d
删除模式空间而不打印,否则默认打印该段落。
这是一个 shell 函数,以您的问题作为输入:
注意 - 为了便于阅读,在本网站的代码突出显示时,对处理后的数据进行了注释。它将按原样工作或没有哈希值。
_pgraph() {
sed '/./{H;$!d};x;/'"$1"'/!d'
} <<\DATA
# I have a file with hundreds of paragraphs of
# around 15 lines each. I need to search for a
# pattern, say Occurance: 1. If this pattern is
# found in the para, I need to print the entire
# paragraph. Note that the paragraps are seperared
# by 2 new line characters.
# I have tried the below line of code and this
# obviously prints the first occurence in the
# file. I am somehow unable to use a loop and
# print all such occurances.
# sed -n '1,/Occurance: 1/p' ystdef.txt | tail -9 >
# ystalarm.txt Can I use the g (global) flag with
# sed to make this work? If yes, how?
# Note that I am aware of the grep -A/B/C commands
# but they wont work on my cygwin terminal.
DATA
现在我可以做:
_pgraph Note
###OUTPUT
# I have a file with hundreds of paragraphs of
# around 15 lines each. I need to search for a
# pattern, say Occurance: 1. If this pattern is
# found in the para, I need to print the entire
# paragraph. Note that the paragraps are seperared
# by 2 new line characters.
# Note that I am aware of the grep -A/B/C commands
# but they wont work on my cygwin terminal.
或者更具体地说:
_pgraph 'Note that I'
# Note that I am aware of the grep -A/B/C commands
# but they wont work on my cygwin terminal.
您可以对任何文件执行相同的操作,而无需将文字输入附加到函数本身,只需删除函数定义中的所有内容并运行它,如下所示<<\DATA
:DATA
_pgraph 'PATTERN' </path/to/input.file
答案3
您可以在 Perl 中使用“段落模式”:
perl -ne 'BEGIN{ $/ = "" } print if /pattern/' input