使用grep在两个单词

时间:2018-01-23 17:22:24

标签: json grep jq

我有一个文件:

{
   "test1": [
        "test_a",
        "test_b",
        "test_c"
   ]
}

我正在尝试提取"test1": []之间存在的文字 我正在尝试这个命令:

cat test | grep -o -P '(?<=test": [).*(?=])'

但它不起作用。一个想法?

谢谢!

4 个答案:

答案 0 :(得分:3)

只需使用 jq 工具:

jq -r '.test1[]' testfile

输出:

test_a
test_b
test_c

答案 1 :(得分:2)

grep不是这项工作的最佳工具,但如果你必须使用它,那么这就有效:

cat test | grep -Pzo '(?s)(?<=test1\": \[)[^\]]*(?=\])'

如果您指定了上面的输入,则此命令的输出为:

    "test_a",
    "test_b",
    "test_c"

在这种情况下,-z选项允许模式跨多行匹配。 (?s)标志使[^ \]]模式也匹配换行符。

jq实用程序专为您要执行的操作而设计:

cat test | jq '.["test"]'

答案 2 :(得分:1)

更新:意外地grep遗憾地能够在多行上进行grep。看到其他一些答案。而且jq真的是工作的正确工具。

尽管如此,这是一个awk解决方案:

$ awk '/]/{p=0}p{print}/test1/{p=1}' test 
    "test_a",
    "test_b",
    "test_c"

或者更通用的

$ awk 'BEGIN{RS="\"test1\": \\[\n|\n[[:blank:]]*\\]"}(RT~/]/){print}' test
    "test_a",
    "test_b",
    "test_c"

第一个解决方案搜索test1并设置要打印的标记(p=1)。如果找到],则会将打印标记设置为零。

第二个解决方案将记录分隔符定义为\"test1\": \\[\n\n[[:blank:]]*\\]。它将检查找到的记录分隔符,如果这是正确的,它将打印。

答案 3 :(得分:0)

sed -n '/"test1": \[/,/\]/{//!p}' test

  • sed -n仅在使用p命令时打印来自模式缓冲区(修改后的输入流)的行。
  • 使用/"test1": \[/语法从模式/\]/到模式/START/,/END/{ ... }
  • //!p仅在与上一场比赛不匹配时打印该线

通用格式为sed -n '/START/,/END/{//!p}' input-file,省略START和END行。或者只是sed -n '/START/,/END/p' input-file,如果你想要它们。