如何解析 JSON 以测试嵌套键的字符串值?

如何解析 JSON 以测试嵌套键的字符串值?

例如,这是我的程序的输出(bspwm,如果您想知道的话):

{
  "id": 29360131,
  "splitType": "vertical",
  "splitRatio": 0.5,
  "birthRotation": 90,
  "vacant": true,
  "sticky": false,
  "private": false,
  "locked": false,
  "presel": null,
  "rectangle": {
    "x": 0,
    "y": 0,
    "width": 1920,
    "height": 1200
  },
  "firstChild": null,
  "secondChild": null,
  "client": {
    "className": "Termite",
    "instanceName": "termite",
    "borderWidth": 1,
    "state": "floating",
    "lastState": "tiled",
    "layer": "normal",
    "lastLayer": "normal",
    "urgent": false,
    "visible": true,
    "icccmFocus": true,
    "icccmInput": true,
    "minWidth": 10,
    "maxWidth": 0,
    "minHeight": 19,
    "maxHeight": 0,
    "wmStatesCount": 0,
    "wmState": [],
    "tiledRectangle": {
      "x": 0,
      "y": 0,
      "width": 958,
      "height": 1198
    },
    "floatingRectangle": {
      "x": 638,
      "y": 394,
      "width": 642,
      "height": 410
    }
  }
}

我想检查一下是"state"不是"tiling"。在这种情况下,它是"floating"

答案1

将 jq 与布尔测试结合使用

假定您的 JSON 存储在名为的变量中json,您可以在 shell 提示符下执行以下操作:

$ echo "$json" | jq '.client.state | test("tiling")'
false

这会正确返回 false,因为您的语料库包含该值floating

否定测试

或者,如果您想测试该值是否为不是 tiling,您可以使用| not过滤器来否定测试的逻辑。例如:

$ echo "$json" | jq '.client.state | test("tiling") | not'
true

这会正确返回 true,因为客户端状态不是tiling,而是floating

提取价值

如果您想确保过滤器以正常的方式工作,您还可以使用 jq 解析该嵌套键的值。例如:

$ echo "$json" | jq .client.state
"floating"

然后,您可以使用该信息来验证您的测试和过滤器,或者如果您不介意生成额外的进程,则只需将其沿着 shell 管道传递给fgrepor 。fgrep -v

答案2

更好的选择是使用 JSON 解析器。

如果你坚持使用grep

假设您grep支持 PCRE ( -P):

bspwm | grep -Po '"state":\K[^,]*'

这将获取 key 的值(带引号)"state"

如果您不想在键周围加上引号:

bspwm | grep -Po '"state":"\K[^"]*'

例如:

% grep -Po '"state":\K[^,]*' <<<'{"id":29360131,"splitType":"vertical","splitRatio":0.500000,"birthRotation":90,"vacant":true,"sticky":false,"private":false,"locked":false,"presel":null,"rectangle":{"x":0,"y":0,"width":1920,"height":1200},"firstChild":null,"secondChild":null,"client":{"className":"Termite","instanceName":"termite","borderWidth":1,"state":"floating","lastState":"tiled","layer":"normal","lastLayer":"normal","urgent":false,"visible":true,"icccmFocus":true,"icccmInput":true,"minWidth":10,"maxWidth":0,"minHeight":19,"maxHeight":0,"wmStatesCount":0,"wmState":[],"tiledRectangle":{"x":0,"y":0,"width":958,"height":1198},"floatingRectangle":{"x":638,"y":394,"width":642,"height":410}}'

"floating"


% grep -Po '"state":"\K[^"]*' <<<'{"id":29360131,"splitType":"vertical","splitRatio":0.500000,"birthRotation":90,"vacant":true,"sticky":false,"private":false,"locked":false,"presel":null,"rectangle":{"x":0,"y":0,"width":1920,"height":1200},"firstChild":null,"secondChild":null,"client":{"className":"Termite","instanceName":"termite","borderWidth":1,"state":"floating","lastState":"tiled","layer":"normal","lastLayer":"normal","urgent":false,"visible":true,"icccmFocus":true,"icccmInput":true,"minWidth":10,"maxWidth":0,"minHeight":19,"maxHeight":0,"wmStatesCount":0,"wmState":[],"tiledRectangle":{"x":0,"y":0,"width":958,"height":1198},"floatingRectangle":{"x":638,"y":394,"width":642,"height":410}}'

floating

答案3

使用专用的 JSON 解析器,例如杰尚,是一种更稳健的方法:

jshon -e client -e state -u < file             
floating

答案4

从 JSON 中提取信息并测试它的另一个简单替代方法是jtc工具(假设源 json 位于file.json):

bash $ cat file.json | jtc -w "[state]:<tiling>" | grep "tiling" >/dev/null; if [ $? == 0 ]; then echo "true"; else echo "false"; fi;
false
bash $ 
bash $ cat file.json | jtc -w "[state]:<floating>" | grep "floating" >/dev/null; if [ $? == 0 ]; then echo "true"; else echo "false"; fi;
true
bash $ 

相关内容