围绕第一场比赛匹配的grep

时间:2014-05-23 12:10:08

标签: grep match

我想在特定文件中使用特定单词'foo',然后在我的匹配项周围获取N行,并仅显示包含第二个grep的块。

我找到了这个,但它确实不起作用......

find . | grep -E '.*?\.(c|asm|mac|inc)$' | \
xargs grep --color -C3 -rie 'foo' | \
xargs -n1 --delimiter='--' | grep --color -l 'bar'

例如我有'a'文件:

a
b
c
d
bar
f
foo
g
h
i
j
bar
l

文件b:

a
bar
c
d
e
foo
g
h
i
j
k

我希望这两个文件都适用于grep -c2,因为bar包含在foo的-c2范围内。我没有得到./bar的任何匹配,因为bar不在foo的-c2范围内......

--
./foo-    bar
./foo-    f
./foo-    **foo**
./foo-    g
./foo-    h
--

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

你可以简单地使用"而读取线"循环:

  

find -regextype posix-extended -regex" ./ file [a-z]" |读线;做grep -nHC2" foo" $ line | grep - color bar;完成

<强>输出:

  

./ filea-5- bar
  ./filec-46 -... host pwns.me [94.23.120.252]:451 4.7.1本地 bar   配置错误......

在这个例子中,我创建了以下文件:
filea - 你的例子a fileb - 你的例子b
filec - 一些随机的exim log输出,foo和bar分开2行 提交 - 相同的exim日志输出,但foo和bar分开3行

您也可以在完成后管道输出,以更改格式:

  

完成| sed&#39; s / - ([0-9] {1,6}) - /:line:\ 1 ::: /&#39;

格式化输出
./filea:line:5 ::: bar
./filec:line:46 ::: ... host pwns.me [94.23.120.252]:451 4.7.1本地 bar 配置错误...

答案 1 :(得分:0)

管道两次

 grep "[^foo\n]" | grep "\n{ntimes}foo\n{ntimes}"

答案 2 :(得分:0)

我想我只理解你问题的第一行,这就是我认为你的意思!

#!/bin/bash
N=2
pattern1=a
pattern2=z
matchinglines=$(awk -v p="$pattern1" '$0~p{print NR}' file)    # Generate array of matching line numbers
for x in ${matchinglines[@]}
do
   ((start=x-N))
   [[ $start -lt 1 ]] && start=1   # Avoid passing negative line nmumbers to sed
   ((end=x+N))
   echo DEBUG: Checking block between lines $start and $end
   sed -ne "${start},${end}p" file | grep -q "$pattern2"
   [[ $? -eq 0 ]] && sed -ne "${start},${end}p" file
done

您需要在脚本开头设置pattern1pattern2。它基本上会做一些awk来构建与第一个模式匹配的行号数组。然后它循环遍历数组并将起始和结束范围设置为每个匹配行号的两侧+/- N.然后,它使用sed对该块进行取样并将其传递给grep,以查看它是否包含pattern2,如果有的话。它可能不是最有效的,但它很容易理解和维护。

它假定您的文件名为file