Skip to content

Instantly share code, notes, and snippets.

@djfdyuruiry
Last active June 21, 2018 22:43
Show Gist options
  • Save djfdyuruiry/6b05ef720b59ff1eb8782e6e92faeac2 to your computer and use it in GitHub Desktop.
Save djfdyuruiry/6b05ef720b59ff1eb8782e6e92faeac2 to your computer and use it in GitHub Desktop.
JSON path bash util function using python, supports array queries, array indices, list object fields and array length query.
#!/usr/bin/env bash
jsonLoadFromStdIn="json.load(sys.stdin)"
loopOverItems=false
loopJsonOperation=""
__doJsonOperation() {
json="$1"
operation="$2"
operationWithJsonLoad=${operation/__JSON__/$jsonLoadFromStdIn}
echo "${json}" | python -c "import sys, json; print ${operationWithJsonLoad}"
}
__convertJsonPathToOperation() {
jsonPath="$1"
jsonPath="${jsonPath:1}"
jsonPath="${jsonPath//[/.[}"
IFS='.' read -ra jsonPathParts <<< "${jsonPath}"
loopOverItems=false
loopJsonOperation=""
jsonOperation="__JSON__"
for jsonPathPart in "${jsonPathParts[@]}"; do
if [ "${jsonPathPart:0:1}" = "[" ] && [ "${jsonPathPart: -1}" = "]" ]; then
# handle array lookups
if [ "${jsonPathPart}" = "[*]" ]; then
# act on all items in array
loopOverItems=true
else
# get item at index in array
if [ "${loopOverItems}" = false ]; then
jsonOperation="${jsonOperation}${jsonPathPart}"
else
loopJsonOperation="${loopJsonOperation}${jsonPathPart}"
fi
fi
elif [ "${jsonPathPart}" = "length()" ]; then
# get length of array
if [ "${loopOverItems}" = false ]; then
jsonOperation="len(${jsonOperation})"
else
loopJsonOperation="${loopJsonOperation}.__len__()"
fi
elif [ "${jsonPathPart}" = "fields()" ]; then
# get fields in object
if [ "${loopOverItems}" = false ]; then
loopOverItems=true
jsonOperation="${jsonOperation}.keys()"
else
loopJsonOperation="${loopJsonOperation}.keys()"
fi
elif [ ! -z "${jsonPathPart}" ]; then
# get object property
if [ "${loopOverItems}" = false ]; then
jsonOperation="${jsonOperation}['${jsonPathPart}']"
else
loopJsonOperation="['${loopJsonOperation}${jsonPathPart}']"
fi
fi
done
echo "jsonOperation=\"${jsonOperation}\"; loopOverItems=${loopOverItems}; loopJsonOperation=\"${loopJsonOperation}\""
}
json-path-query() {
json="$1"
jsonPath="$2"
if [ -z "${json}" ] || [ -z "${jsonPath}" ]; then
>&2 echo "Usage: $0 json jsonPath"
return 1
fi
eval $(__convertJsonPathToOperation "${jsonPath}")
if [ "${loopOverItems}" = false ]; then
__doJsonOperation "${json}" "${jsonOperation}"
return 0
fi
isDictionary="$(__doJsonOperation "${json}" "isinstance(${jsonOperation}, dict)" | tr '[:upper:]' '[:lower:]')"
numItems="$(__doJsonOperation "${json}" "len(${jsonOperation})")"
if [ "${isDictionary}" = true ]; then
jsonOperation="list(${jsonOperation}.values())"
fi
for ((i=0; i < ${numItems}; i++)); do
__doJsonOperation "${json}" "${jsonOperation}[${i}]${loopJsonOperation}"
done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment