Fah*_*tha 7 grep text-processing
考虑以下玩具示例:
this is a line
this line contains FOO
this line is not blank
This line also contains FOO
Some random text
This line contains FOO too
Not blank
Also not blank
More random text
FOO!
Yet more random text
FOO!
Run Code Online (Sandbox Code Playgroud)
所以,我想要 FOO 的 grep 的结果,但有额外的皱纹,应该包括匹配行之后的行,只要它们不是空白,并且它们本身不包含 FOO。因此匹配将如下所示,不同的匹配分开:
匹配 1
this line contains FOO
this line is not blank
Run Code Online (Sandbox Code Playgroud)
第 2 场
This line also contains FOO
Run Code Online (Sandbox Code Playgroud)
第 3 场
This line contains FOO too
Not blank
Also not blank
Run Code Online (Sandbox Code Playgroud)
第 4 场
FOO!
Yet more random text
Run Code Online (Sandbox Code Playgroud)
第 5 场
FOO!
Run Code Online (Sandbox Code Playgroud)
可以在命令行上运行的简单单行脚本的加分点(比喻地说)。
附录:如果不是太难,添加比赛号码的运行计数会非常方便。
使用awk而不是grep:
awk '/FOO/ { if (matching) printf("\n"); matching = 1 }
/^$/ { if (matching) printf("\n"); matching = 0 }
matching' file
Run Code Online (Sandbox Code Playgroud)
枚举匹配项的版本:
awk 'function flush_print_maybe() {
if (matching) printf("Match %d\n%s\n\n", ++n, buf)
buf = ""
}
/FOO/ { flush_print_maybe(); matching = 1 }
/^$/ { flush_print_maybe(); matching = 0 }
matching { buf = (buf == "" ? $0 : buf ORS $0) }
END { flush_print_maybe() }' file
Run Code Online (Sandbox Code Playgroud)
这两个awk程序都使用一个非常简单的“状态机”来确定它当前是否匹配。模式匹配FOO将使其进入matching状态,模式匹配^$(空行)将使其进入非matching状态。
匹配数据集之间的空行的输出发生在从 matching(进入matching或进入非matching)的状态转换时。
第一个程序在该matching状态下打印任何行。
第二个程序buf在处于matching状态时收集变量中的行。它在可能打印后刷新(清空)它(取决于状态),以及Match N状态转换时的标签(当第一个程序输出空行时)。
最后一个程序在样本数据上的输出:
Match 1
this line contains FOO
this line is not blank
Match 2
This line also contains FOO
Match 3
This line contains FOO too
Not blank
Also not blank
Match 4
FOO!
Yet more random text
Match 5
FOO!
Run Code Online (Sandbox Code Playgroud)
sed -ne '/FOO/{x;P;x};/FOO/,/^$/p' testfile
Run Code Online (Sandbox Code Playgroud)
输出中的每个非空行块都是来自输入的单个匹配数据块。换行符的数量各不相同。
这个
-n); 然后/FOO/{x;P;x}- 使用空的保持空间);/FOO/)的行开始并以空行 ( /^$/)结束的行选择范围;最后p)。this line contains FOO
this line is not blank
This line also contains FOO
This line contains FOO too
Not blank
Also not blank
FOO!
Yet more random text
FOO!
Run Code Online (Sandbox Code Playgroud)
我不认为这是可行的grep,但它适用于 AWK:
#! /usr/bin/awk -f
/FOO/ {
matched = 1
if (notfirst) print ""
notfirst = 1
}
/^$/ {
matched = 0
}
matched
Run Code Online (Sandbox Code Playgroud)
随着比赛的数量:
#! /usr/bin/awk -f
/FOO/ {
matched = 1
if (matches) print ""
printf "Match %d\n", ++matches
}
/^$/ {
matched = 0
}
matched
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,前两个块确定是否应将当前记录复制到输出。当前记录匹配“FOO”时,第一个块设置matched为1,必要时输出一个空白记录(将即将到来的输出与前一个匹配分开);在第二个变体中,它还增加matches计数器并输出一个标题。当前记录为空时,第二个块设置matched为0。matched如果matched为1,则孤独条件打印当前记录。