使用grep查找每个包含所有搜索字符串的行

时间:2014-04-05 16:57:31

标签: linux bash grep

我有一个包含许多与此类似的行的文件:

{"id": 2796, "some_model": "Profile", "message_type": "MODEL_SAVE", "fields": {"account": 14, "address": null, "modification_timestamp": "2014-03-19T10:46:33.543Z", "was_deleted": false}}

但是我想找到所有的线条,它们只包含我想要的各条线。将在上面的示例行中应用的示例是:

~$ grep '2796' file.log | grep 'Profile' | grep 'another_more' | grep 'so_on'

我尝试过与上面相同的方式,已编辑:它确实有效,但还不足以带来所有必要的数据。我的意思是,搜索结果中缺少数据。 :(

遵循grep 'word' filename它的作用,但只有一个数据山中的一个词是不够的。那么,如何传递多个'单词'来匹配我真正想要的东西?我真正想要的是同时使用grep搜索' ID ','* some_model *'和' account '。

如何进行搜索以将所有可能的行与提示中的参数匹配? 这更像是一个疑问,是否可以使用像ifelse o while这样的条件,例如与grep结合使用?

如果问题不明确,请让我知道。 谢谢大家。

4 个答案:

答案 0 :(得分:3)

您可以使用sed

sed '/string1/!d; /string2/!d; /string3/!d; /string4/!d' filename

这将只生成包含任何顺序的所有字符串的行。

使用awk同样的事情:

awk '/string1/ && /string2/ && /string3/ && /string4/' filename

答案 1 :(得分:1)

此问题专门询问grep,但真正的sedawk对于'a AND b'式比赛更加清晰,请参阅How to run grep with multiple AND patterns? < / em>的

此答案涵盖了如何使用grep匹配所有与所有输入相匹配的行 - my other answer涵盖匹配任何输入。

请注意grep比简单的单词匹配更强大,它可以匹配任意模式,包括多个单词。

考虑您提供的示例的以下简化版本:

$ cat file
{"id": 2796, "some_model": "Profile", "was_deleted": false}
{"id": 2797, "some_model": "Profile", "was_deleted": true}
{"id": 2798, "some_model": "Another", "was_deleted": false}

您可以像这样找到项目2796:

$ grep '"\?id"\? *: *2796 *,\?' file
{"id": 2796, "some_model": "Profile", "was_deleted": false}

或查找所有未删除的项目:

$ grep '"\?was_deleted"\? *: *false *[,}]' file
{"id": 2796, "some_model": "Profile", "was_deleted": false}
{"id": 2798, "some_model": "Another", "was_deleted": false}

你甚至可以将两者结合起来,只有在没有删除时才能获得第2796项(将false更改为true并且该行不再匹配):

$ grep '"\?id"\? *: *2796 *,\?.*"\?was_deleted"\? *: *false *[,}]' file
{"id": 2796, "some_model": "Profile", "was_deleted": false}

或大致相当,使用您在上面使用的grep-piping语法:

$ grep '"\?id"\? *: *2796 *,\?' file | grep '"\?was_deleted"\? *: *false *[,}]'
{"id": 2796, "some_model": "Profile", "was_deleted": false}

这些例子看起来很难做到正确,因为这不是一个好主意!

您正在使用的数据看起来是JSON,这是一种结构化数据格式,grep不适合处理。有效的JSON可以跨多行分割或具有任意顺序的字段,这将破坏上述模式。更不用说上面的模式应该处理的任意空格(*),半可选引号("\?),以及字段结束与对象标记结束([,}]) ,但很容易出错。

如果您正在尝试查询JSON数据,则需要一个JSON解析器,而grep则不需要。 http://www.json.org/提供了许多语言中几种流行的JSON解析器的链接,看看是否有任何一种可以满足您的需求。使用真实工具比尝试构造复杂的正则表达式会有更好的成功。

答案 2 :(得分:0)

这个答案涵盖了如何使用grep来匹配所有匹配多个输入之一的行 - my other answer涵盖匹配所有输入,OP实际上正在寻找。我怀疑这个答案更常见于人们正在寻找的东西,所以我将它留在这里。

-e参数可让您搜索多个不同的匹配项:

$ cat file
Hello World
Nope
Foo Bar

$ grep -e Hello -e Foo file
Hello World
Foo Bar

您还可以使用|字符在单个查询中分隔多个匹配项,但您必须使用\对其进行转义并引用查询字符串,如下所示:

$ grep 'Hello\|Foo' file
Hello World
Foo Bar

或使用f标志在文件中指定grep使用模式:

$ cat patterns
Hello
Foo

$ grep -f patterns file
Hello World
Foo Bar

毋庸置疑,我个人更喜欢使用-e,但有很多选择。

答案 3 :(得分:0)

我相信官方GNU grep文档中已经回答了这个问题:

http://www.gnu.org/savannah-checkouts/gnu/grep/manual/grep.html#Usage

10.  I can do “OR” with ‘|’, but what about “AND”?

    grep 'paul' /etc/motd | grep 'franc,ois' 

finds all lines that contain both ‘paul’ and ‘franc,ois’.

看起来是使用grep实现逻辑 AND 的唯一方法,它不依赖于找到匹配模式的顺序。