【问题标题】:Filter by Regex in JQ在 JQ 中按正则表达式过滤
【发布时间】:2018-11-24 20:44:03
【问题描述】:
[{
  "Address": "The Sq"
 },
 {
  "Address": "1 Bridge Rd"
}]

使用以下 JSON,我如何使用 JQ 编写一个脚本来过滤一个正则表达式,我希望结果只是以数字作为第一个字符的地址。我使用

构建这个 JSON
map({ Address: .[].payload.address })

如何添加到这里以过滤我想要的正则表达式(即 \A[0-9])

【问题讨论】:

    标签: json regex bash command-line jq


    【解决方案1】:

    虽然接受的答案有效,但我觉得这更具可读性

    $
    $ echo '[{"Address": "The Sq", "n": 1}, {"Address": "1 Bridge Rd", "n": 2}]' | \
      jq '.[] | .Address | select(.|test("^[0-9]"))'
    
    "1 Bridge Rd"
    $
    $ echo '[{"Address": "The Sq", "n": 1}, {"Address": "1 Bridge Rd", "n": 2}]' | \
      jq '.[] | select(.Address|test("^[0-9]"))'
    
    {
      "Address": "1 Bridge Rd",
      "n": 2
    }
    $
    

    如果你想做一些不同的过滤:

    $ echo '[{"name": "john doe", "sex": "male", "age": 26, "occupation": "city planner", "cod": "asphyxiation"}, {"name": "jane doe", "sex": "male", "age": 24, "occupation": "beautician", "cod": "strangulation"}, {"name": "crispy lips", "sex": "male", "age": 38, "occupation": "convicted killer"} ]' > in.json
    $ cat in.json | jq .
    [
      {
        "name": "john doe",
        "sex": "male",
        "age": 26,
        "occupation": "city planner",
        "cod": "asphyxiation"
      },
      {
        "name": "jane doe",
        "sex": "male",
        "age": 24,
        "occupation": "beautician",
        "cod": "strangulation"
      },
      {
        "name": "crispy lips",
        "sex": "male",
        "age": 38,
        "occupation": "convicted killer"
      }
    ]
    $
    

    然后我们可以像这样进行基本的正则表达式过滤/转换:

    $ cat in.json | jq '.[] | .name'
    "john doe"
    "jane doe"
    "crispy lips"
    $
    $ cat in.json | jq '.[] | .name | select(.|test(".*doe"))'
    "john doe"
    "jane doe"
    $
    $ cat in.json | jq '.[] | select(.name|test(".*doe"))'
    {
      "name": "john doe",
      "sex": "male",
      "age": 26,
      "occupation": "city planner",
      "cod": "asphyxiation"
    }
    {
      "name": "jane doe",
      "sex": "male",
      "age": 24,
      "occupation": "beautician",
      "cod": "strangulation"
    }
    $ 
    $ cat in.json | jq '.[] | select(.name|test(".*doe")) | {n: .name, a: .age}'
    {
      "n": "john doe",
      "a": 26
    }
    {
      "n": "jane doe",
      "a": 24
    }
    $ 
    $ 
    

    【讨论】:

      【解决方案2】:

      如果您将以下过滤器添加到您已有的过滤器上,那么您将获得如下所示的输出:

      map(select(.Address | test("^[0-9]")))
      

      输出:

      [
        {
          "Address": "1 Bridge Rd"
        }
      ]
      

      为了稳健性,您不妨考虑在测试后添加?

      map(select(.Address | test("^[0-9]")?))
      

      或者,您可以通过多种方式组合对map 的两次调用。您不妨考虑:

      .[].payload.address | select(test("^[0-9]")?) | {Address: .}
      

      【讨论】:

      • 你的意思是我应该运行map({ Address: .[].payload.address }) | map(select(.Address | test("^[0-9]")))?,我得到一个错误:null(null)不能匹配,因为它不是一个字符串
      • 在您的问题中,您指出 JSON 是给定 map 过滤器的输出。我已经验证,如果是这样的话,输出如图所示。如果您更严格地遵循 mcve 指南,也许会有所帮助:stackoverflow.com/help/mcve
      • 您好,很抱歉给您带来了困惑。我理解您的回答,其中一个正在构建我提供的代码,但两种解决方案似乎都会给我一个错误。
      • 更新后的答案有一个您可能会觉得有帮助的建议。
      • 你好峰,非常感谢你的帮助!你是我的救星!!
      猜你喜欢
      • 2014-10-17
      • 2022-10-04
      • 2016-01-19
      • 2014-11-27
      • 1970-01-01
      • 2015-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多