【问题标题】:grep - print next 10 lines if the line containing one word but not another in the same linegrep - 如果该行包含一个单词但在同一行中不包含另一个单词,则打印接下来的 10 行
【发布时间】:2014-08-01 17:47:49
【问题描述】:

我有一个包含行的文件,如下所示:

some strings here class="batch2010" some more strings here click-here
<about 20-30lines here>
some strings here class="batch2006" some more strings here click-here
<about 20-30lines here>
some strings here class="NA" some more strings here click-here
<about 20-30lines here>
some strings here class="batch2010" some more strings here access-denied
<about 20-30lines here>

我想打印包含以下内容的行:

class="batch2010"

但不是:

access-denied

在同一行,然后打印文件中的下 10 行。

除了编写一个很长很复杂的shell脚本之外,还有其他方法吗?

【问题讨论】:

  • 1) 下一行中的访问被拒绝且符合条件的行呢? 2)在一次出现的后续行中的 10 行中的几条符合条件的行怎么样(分别打印每个或直到块中最后一个符合条件的最后 10 行或仅部分直到下 10 行而不是新的出现,...)?
  • @NeronLeVelu 在接下来的 10 行中出现 access-denied 行的可能性为零。因此,它会自动互斥。

标签: bash awk sed grep


【解决方案1】:

这可能是一个解决方案:

awk 'lines>0 {print; --lines}
     /ass="batch2010"/ && !/access-denied/ {lines=10}' file

查看输出(不是很相关,因为行数不多):

$ awk '(lines>0) {print; --lines} /ass="batch2010"/ && !/access-denied/ {lines=10}' a
some strings here class="batch2006" some more strings here click-here
some strings here class="NA" some more strings here click-here
some strings here class="batch2010" some more strings here access-denied

它的逻辑是基于How to print 5 consecutive lines after a pattern in file using awk添加我们匹配ass="batch2010"和“不匹配”access-denied的部分。

测试

$ seq 30 > a
$ awk 'lines>0 {print; --lines} /4/ && !/14/ {lines=10}' a
5
6
7
8
9
10
11
12
13
14
25
26
27
28
29
30

【讨论】:

  • 为什么不只是awk 'lines&gt;0 {print; --lines} /ass="batch2010"/ &amp;&amp; !/access-denied/ {lines=10}' a
  • 你说的很对,@Jotne,很好!刚刚相应更新,谢谢。
  • 或者只是awk 'lines--&gt;0; /ass="batch2010"/ &amp;&amp; !/access-denied/ {lines=10}' a :)
  • 嗯...这有点太多了 :D 我更喜欢代码有点自动解释!
【解决方案2】:

你可以试试

< thefile grep -v 'access-denied' | grep -A10 'class="batch2010"'

【讨论】:

  • 不太确定这是否正是 OP 所要求的。在class="batch2010" 之后的接下来的 10 行中有一行包含access-denied 是什么?然后,该行将不会被打印。
  • 我同意。如果 OP 明确表示这种情况,我将删除我的答案。
【解决方案3】:

这可能适用于 yoyu (GNU sed):

sed -n '/access-denied/b;/class="batch2010"/{:a;$!{N;s/\n/&/10;Ta};p}' file

如果 line 包含 access-denied,则退出,否则如果 line 包含 class="batch2010",则读取接下来的 10 行并打印出来。

【讨论】:

    【解决方案4】:

    这个 sed 命令应该可以工作
    sed 处于非打印模式。
    如果找到denied,则中断并跳转到 sed 语句的末尾。
    如果不是,则查找 2010 并打印接下来的 10 行

    sed -n '/denied/b;/2010/,+10p' file
    

    【讨论】:

    • 这将错过2010 之后的 10 行中的 denied 行。
    • @potong 为什么这很重要?
    • 问题是“grep - 如果同一行中包含一个单词但不包含另一个单词,则打印接下来的 10 行”它没有说明过滤这 10 行。
    • 但是你还是想跳过被拒绝的行?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    相关资源
    最近更新 更多