反向grep的A

时间:2015-05-20 16:31:24

标签: linux shell grep

我知道我可以使用grep打印与-A1匹配的“下一行”,但是相反的是什么呢?我的意思是“在过滤器匹配后隐藏下一行”。

示例:

a
b
c
d
e

cat letters.txt | grep -A1 -v "c"< - 隐藏“c”和“d”

4 个答案:

答案 0 :(得分:4)

grep本身并不(通常)提供此功能,但使用Awk或sed很容易。

awk '/c/ { skip=1; next }
    skip { skip=0; next } 1' letters.txt

答案 1 :(得分:2)

您可以使用sed

来执行此操作
sed -ne '/c/{n;d;}; p' letters.txt

这将读取文件letters.txt。将打印与c不匹配的任何行,如果匹配c,则不打印,并转到下一行并从输出中删除

使用GNU sed可以更容易地获得N行,可以像

那样完成
sed -ne '/c/,+1d; p;' letters.txt

您可以将1更改为您喜欢的任何数字。此外,您可以将-i标记添加到sed,以便在需要时将其修改为文件

答案 2 :(得分:2)

此答案通过变量跳过计数查看一般解决方案。

如果你有 GNU sedEric Renouf's elegant answer是最简单的解决方案。

它可以略微简化为sed '/c/,+1d',或者概括为:

regex='c' count=2
sed "/${regex}/,+${count}d" letters.txt  # skips c, d, e

+<n>形式的上下文地址,用于匹配范围开头的<n> - 行 (因此范围的起点通过以下<n>行)是GNU sed扩展名。

请注意,会跳过$count +1 行:之后与正则表达式+ $count匹配的行。

为了便于携带以获得更多灵活性(例如不跳过匹配的行本身),请使用 tripleee's helpful awk answer的广义版本< /强>:

awk -v regex='c' -v count=2 \
  '$0 ~ regex { skip=count; next } --skip >= 0 { next } 1' letters.txt # skips c, d, e

请注意,会跳过$count +1 行:之后与正则表达式+ $count匹配的行。

  • -v regex='c' -v count=2定义具有指定值的awk变量。
  • $0 ~ regex匹配感兴趣的线条
    • { skip=count; next }初始化跳过计数并继续到下一行,有效地跳过匹配行;在第二个解决方案中,print之前的next确保跳过。
    • --skip >= 0减少跳过次数,如果(仍然)> = 0则采取措施,这意味着应该跳过手边的行。
    • { next }进入下一行,有效地跳过当前行
  • 1{ print }的常用简写;也就是说,简单地打印当前行
    • 只有非匹配和非跳过的行才能到达此命令。
    • 1等同于{ print }的原因是1被解释为布尔模式,根据定义,它总是计算为true,这意味着它的相关操作( block)无条件执行。由于在这种情况下存在关联操作,awk默认为打印该行。

作为符合POSIX标准的 shell功能

# SYNOPSIS
#   matchAndSkip regex skipCount [file]
matchAndSkip() {
  awk -v regex="$1" -v count="$2" \
    '$0 ~ regex { skip=count; next } --skip >= 0 { next } 1' "${3-/dev/stdin}"
}

答案 3 :(得分:1)

使用awk你也可以这样做:

awk -v s='c' '$0 ~ s {getline;next} 1' letters.txt
a
b
e