在 bash 中第 n 次出现后打印几行

在 bash 中第 n 次出现后打印几行

我正在寻找一种方法来搜索模式的第 n 次出现并在模式后打印 k 行。我想awk会比grep这种情况更好,但我不知道如何正确地做到这一点......

假设我有以下文本文件:

Draft  
blablablabla  
tralalalalala  
Draft  
blablablabla  
tralalalalala  
Draft  
important line 1  
important line 2  
Draft   
blablablabla   
tralalalalala  

在本例中n=3k=2我想打印模式“Draft”第 3 次出现后的 2 行。在我的具体情况下,n 和 k 可能会有所不同。

这是一个简单的方法吗?

答案1

Perl 来救援:

 perl -sne '$c++ if /Draft/;
            if ($c == $n) { print scalar <> for 1 .. $k; }
           ' -- -n=3 -k=2 < input
  • -s解析开关-n=3并创建变量。
  • -n逐行读取输入。
  • <>菱形运算符从输入中读取。
  • 标量只需要从输入中读取一行,否则打印将在菱形运算符上强制列出上下文并打印所有剩余的行。

答案2

awk:打印第三行和第四行“草稿”之间的行。

awk -v n=3 '/Draft/ { p = (++num == n) ; next }; p' file

有一个优化要做:看到第四稿时退出。

答案3

您可以使用greptail来实现此目的:

$ n=3
$ k=2
$ grep -m "$n" -A "$k" 'Draft' input.txt | tail -n "$k"
important line 1  
important line 2  
$ 

grep 的选项-m "$n"指定在第 次匹配后停止n,并告诉 grep在每次匹配后-A "$k"输出行。k然后我们通过管道将tail -b "$k"其仅输出这些k行。

答案4

sed  -ne'/^\(.*\n\)*Draft *$/G'  \
     -e's/\n/&/3;t$' -e'N;D;:$'  \
     -e's///g;//!n;N;G;s/\n//2'  \
     -etq -e/.$/b$ -e:q -e'p;q' <in >out

important line 1
important line 2

相关内容