我有一个包含许多与此类似的行的文件:
{"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 '。
如何进行搜索以将所有可能的行与提示中的参数匹配?
这更像是一个疑问,是否可以使用像if
和else
o while
这样的条件,例如与grep结合使用?
如果问题不明确,请让我知道。 谢谢大家。
答案 0 :(得分:3)
您可以使用sed
:
sed '/string1/!d; /string2/!d; /string3/!d; /string4/!d' filename
这将只生成包含任何顺序的所有字符串的行。
使用awk
同样的事情:
awk '/string1/ && /string2/ && /string3/ && /string4/' filename
答案 1 :(得分:1)
此问题专门询问grep
,但真正的sed
或awk
对于'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 的唯一方法,它不依赖于找到匹配模式的顺序。