Awk grep-打印前一行,don';t打印匹配

Awk grep-打印前一行,don';t打印匹配,awk,grep,Awk,Grep,如何轻松打印匹配上方的行并跳过匹配本身grep-A、-B和-o选项不解决此问题。也许是一些awkmagic 例如: $ cat foo.txt bar foo baz foo $ cat foo.txt | grep foo-SOMETHING bar baz 编辑 如果第2行和第3行有“foo”,则应打印第1行和第2行(尽管我在这里不是很严格) 附加特征:考虑例子: bar foo baz foo foo 这应该是理想的回报 bar baz foo 第一个子句将每个非foo行保存在

如何轻松打印匹配上方的行并跳过匹配本身
grep
-A
-B
-o
选项不解决此问题。也许是一些
awk
magic

例如:

$ cat foo.txt
bar
foo
baz
foo

$ cat foo.txt | grep foo-SOMETHING
bar
baz
编辑

  • 如果第2行和第3行有“foo”,则应打印第1行和第2行(尽管我在这里不是很严格)

附加特征:考虑例子:

bar
foo
baz
foo
foo
这应该是理想的回报

bar
baz
foo
第一个子句将每个非foo行保存在一个变量中。第二个子句在行与
foo
匹配时打印最近保存的行

这同样有效(并处理一行中有两行
foo
的情况):

使用
grep
可以执行以下操作:

grep -B 1 foo foo.txt | grep -vE 'foo|^--$'

第二个命令过滤掉匹配块之间打印的
foo
行和分隔符。

只需将
p
设置为所需的模式:

$ awk '$0~p{print a}{a=$0}' p="foo" file
bar
baz
foo

-B
有什么问题吗?@AdrianFrühwhirth它打印前一行和匹配行。两条连续行都匹配
foo
?打印第一行?或者忽略两者?@Barmar:我知道,但这是可以解决的。如果包含
foo
的行后面跟一行匹配的
foo
,则应将其重构为
awk'/foo/{print line}{line=$0}'foo.txt
不应
awk'/foo/{print line}{line=$0}'foo.txt
足够吗?@AdrianFrühwirth:请将其作为答案发布,它在处理重复匹配模式时表现更好(参见编辑的问题)@JakubM。这是我的答案,也是维杰的答案。@Barmar:我以为阿德里安在你之前,对不起,如果我错了
grep -B 1 foo foo.txt | grep -vE 'foo|^--$'
$ awk '$0~p{print a}{a=$0}' p="foo" file
bar
baz
foo
awk '/foo/{print a}{a=$0}' your_file