How to trim white space for every element in JQ?
If the input is an array of JSON objects and if you're looking for a one-liner, then the following seems to meet your requirements:
jq '.[]|(.k1,.k2)|if type=="string" then gsub("^\\s+|\\s+$";"") else . end' | paste -d "," - -
With your input, this produces
"http://url",null
If you are flexible about how null
is presented in the output, you might also consider an all-jq solution (i.e. without paste
). For example:
jq -r '.[]|[.k1,.k2]|map(if type=="string" then gsub("^\\s+|\\s+$";"") else . end)|@csv'
With your input, this produces:
"http://url",
The below will remove leading and trailing spaces in strings anywhere inside an arbitrarily complex JSON structure:
#!/usr/bin/env jq -cf# Define walk function (standard library only for jq 1.6 and newer, currently unreleased)def walk(f): . as $in | if type == "object" then reduce keys_unsorted[] as $key ( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f elif type == "array" then map( walk(f) ) | f else f end;walk( if type == "string" then (sub("^[[:space:]]+"; "") | sub("[[:space:]]+$"; "")) else . end)
If one saves the above (e.g. in trim-json
), and marks it executable (chmod +x trim-json
), then ./trim-json <<<"$json"
with your given input emits:
[{"k1":"v1","k2":"v2","k3":"v3","k4":"v4"}]
Similarly, with the updated input:
$ json='[{"k1":" http://url", "k2":null, "k3":" v3", "k4":" v4"}]'$ ./trim-json <<<"$json"[{"k1":"http://url","k2":null,"k3":"v3","k4":"v4"}]
The example has a space in front of every value. For the case where you can simply remove the first (or N) characters of a string, then a simple map over range slicing works:
$ jq -c '.[] | map_values(.[1:]) | .k1,.k2' <<< "$json" | paste -d "," - -"http://url",null
This approach has the benefit of being unpretentious and simple to understand.