skip to Main Content

I am currently working with i3 and would like to parse the visible workspaces with i3-msg -t get_workspaces, to "save the workspace" and return to them when my pomodoro break is over, problem is I’ve never worked with json in bash before (aside from a couple quick examples maybe an hour ago).
basically I am trying to return the name value of the visible workspaces.

[
  {
    "id": 94475011596992,
    "num": 6,
    "name": "6:NoteTaking",
    "visible": false,
    "focused": false,
    "rect": {
      "x": 40,
      "y": 65,
      "width": 1840,
      "height": 975
    },
    "output": "DisplayPort-2",
    "urgent": false
  },
  {
    "id": 94475011603104,
    "num": 7,
    "name": "7:Entertainment",
    "visible": false,
    "focused": false,
    "rect": {
      "x": 40,
      "y": 65,
      "width": 1840,
      "height": 975
    },
    "output": "DisplayPort-2",
    "urgent": false
  },
  {
    "id": 94475011612464,
    "num": 9,
    "name": "9",
    "visible": true,
    "focused": true,
    "rect": {
      "x": 40,
      "y": 65,
      "width": 1840,
      "height": 975
    },
    "output": "DisplayPort-2",
    "urgent": false
  },
  {
    "id": 94475011631328,
    "num": 1,
    "name": "1:Browsing",
    "visible": true,
    "focused": false,
    "rect": {
      "x": 40,
      "y": 1145,
      "width": 1840,
      "height": 975
    },
    "output": "DisplayPort-1",
    "urgent": false
  },
  {
    "id": 94475011637712,
    "num": 2,
    "name": "2:Messaging",
    "visible": false,
    "focused": false,
    "rect": {
      "x": 40,
      "y": 1145,
      "width": 1840,
      "height": 975
    },
    "output": "DisplayPort-1",
    "urgent": false
  },
  {
    "id": 94475011644096,
    "num": 3,
    "name": "3",
    "visible": false,
    "focused": false,
    "rect": {
      "x": 40,
      "y": 1145,
      "width": 1840,
      "height": 975
    },
    "output": "DisplayPort-1",
    "urgent": false
  }
]

Currently I have this line doing most of the heavy lifting,

  local currentWorkspaces=$(i3-msg -t get_workspaces | jq -r 'map(select(.visible == true)).name')

it’s returning the right values (granted they are in quotes.)

[
  "9",
  "1:Browsing"
]

I’ve been trying to call them with a simple array (never worked with arrays either so might be messing stuff up)
i3-msg workspace "$currentWorkspaces[@]"

currently I have no idea how to move forward, and any help would be appreciated (-r the option I thought would return the values without quotes isn’t doing so)

2

Answers


  1. Assuming the values in .name have no spaces or certain other characters,
    you would be able to get away with something along the lines of the following:

    X=$(i3-msg -t get_workspaces | jq -r '.[] | select(.visible == true).name' )
    
    for var in "${X[@]}"
    do
      echo "$var"
    done 
    

    Output:

    9
    1:Browsing
    

    More robustly, if your shell has readarray:

    readarray -t X < <(... | jq -r '.[] | select(.visible == true).name ')
    

    Otherwise, you could use the idiom:

    vars=(); while IFS= read -r line; do vars+=("$line"); done < .....
    
    Login or Signup to reply.
  2. the ideal solution would be to have it stored in a array

    Assuming you mean a bash array, you can use declare to declare it, and use jq’s @sh to properly escape the contents.

    For an indexed array, use declare -a:

    $ declare -a cw="($(i3-msg … | jq -r '.[]  | select(.visible).name | @sh'))"
    
    $ declare -p cw  # print for testing
    declare -a cw=([0]="9" [1]="1:Browsing")
    

    For an associative array, use declare -A, and output each keys before its value:

    $ declare -A cw="($(i3-msg … | jq -r '.[]  | select(.visible) | .output, .name | @sh'))"
    
    $ declare -p cw  # print for testing
    declare -A cw=([DisplayPort-2]="9" [DisplayPort-1]="1:Browsing" )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search