使用 -v 选项反转多行 grep 结果,但 grep -A 不起作用

Using -v option to invert multi-line grep results with grep -A not working

我有如下列表:

Name_JR_1
1.1.1.1
Name_SR_1
2.2.2.2
Name_NONE_1
3.3.3.3

如果我想选择所有具有以下数字语法的关联名称,我可以使用 -A1 选项查找模式并打印匹配行加上之后的上下文或下一行,如下所示:

grep "JR" -A1 file_name

这将打印我想要的内容:

Name_JR_1
1.1.1.1

但是我需要一种方法来反转它,在那里我可以删除与搜索模式匹配的所有条目。但是,使用具有此语法的 -v 选项不会给我想要的结果:

grep -v "JR" -A1 file_name

我希望执行此命令后的输出如下:

Names_SR_1
2.2.2.2
Name_NONE_1
3.3.3.3.

尝试:

$ awk '/JR/{getline;next} 1' file
Name_SR_1
2.2.2.2
Name_NONE_1
3.3.3.3

工作原理

  1. /JR/{getline;next}

    这将选择包含 JR 的行。对于这些行,这指示 awk 获取下一行 (getline),然后跳过其余命令并从下一行 (next) 重新开始。

  2. 1

    对于其中没有 JR 的任何行,这将打印该行。

另一个 awk:

$ awk '/JR/||f==1{f=!f;next}1' file
Name_SR_1
2.2.2.2
Name_NONE_1
3.3.3.3

如果我们看到 JR 或标志升起,反转标志并跳到下一行。

您也可以使用sed

$ sed '/JR/{N;d;}' ip.txt
Name_SR_1
2.2.2.2
Name_NONE_1
3.3.3.3
  • N 将下一行添加到模式 space 然后 d 将删除它
    • 使用 N;N 多两行,N;N;N 多三行,依此类推


对于 awk

的通用解决方案
$ awk '/JR/{c=2} !(c && c--)' ip.txt
Name_SR_1
2.2.2.2
Name_NONE_1
3.3.3.3
  • 这里2是匹配行数和
  • 之后的一行数
  • 所以对于 -A2 等效项,您需要 c=3
  • 请参阅 Printing with sed or awk a line following a matching pattern 了解大量与此相关的案例