For example, here is my program's output (bspwm, if you wanted to know):

  "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

I want to check if "state" is not "tiling". In this case, it is "floating".

  • If str is the long string you present, then: echo "$str" | grep -oP '"state":"\K([^"]*)' – user79743 Feb 24 '16 at 6:02
  • <your program> | grep -q '"state": *"tiling"' || echo not tiling` Or use a json parser like jq. – cuonglm Feb 24 '16 at 6:22

Using jq with Boolean Tests

Given that your JSON is stored in a variable named json, you could do the following at the shell prompt:

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

This correctly returns false because your corpus contains the value floating instead.

Negating Tests

Alternatively, if you wanted to test that the value is not tiling, you can use the | not filter to negate the logic of your test. For example:

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

This correctly returns true because the client state isn't tiling, it's floating.

Extracting the Value

In case you want to make sure your filters are working in a sane way, you can also use jq to parse out the value for that nested key. For example:

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

You can then use that information to validate your tests and filters, or simply pass it along a shell pipeline to fgrep or fgrep -v if you don't mind spawning an additional process.


Better option is to use a JSON parser.

If you insist on using grep:

Assuming your grep supports PCRE (-P):

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

This will get the value (with quotes) of the key "state".

If you don't want surrounding quotes around the key:

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

For example:

% 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}}'


% 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}}'

  • Why don't grep directly, like grep -q '"state": *"tiling"'? – cuonglm Feb 24 '16 at 6:29

Using a dedicated JSON parser, like Jshon, is a more robust approach:

jshon -e client -e state -u < file             

another easy alternative to extract info from JSON and test it is jtc tool (assuming source json is in file.json):

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy