#!/bin/bash # # Author: Georg Voell - georg.voell@oracle.com # Version: @(#)norm-json 3.0.1 21.03.2021 (c)2021 Oracle # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/ # #@ Normalize JSON records and pretty print them. #@ #@Usage: norm-json [options] #@ Options: '-h, --help' : Displays helptext. #@ '-v, --version' : Displays the version of the script. #@ '-q, --quiet' : Just write error message to LOGFILE. #@ '-r, --raw' : Don't convert hyphens e.g. lifecycle-state to lifecycleState #@ '-n, --number' : Extract only the nth JSON record (starting with 0 for the first record). #@ '-f, --filename' : JSON file to read from - if not specified, read from stdin. # # Exit codes: # 01: Unknown or wrong parameter. # 02: No **jq** or wrong version of **jq**. This script needs **jq** to format "json". # 03: Error in JSON file or no input. # 04: JSON file contains less then 2 lines. # 05: JSON file doesn't contain records. # 06: JSON file doesn't contain specified record. # 99: User interrupt. # # Update history: # # V 3.0.0 10.01.2021 New version # V 3.0.1 21.03.2021 New paramater "--quiet" # V 3.0.2 24.03.2021 Strip comments beginning with // # script=${0} # Name of this script progstr=`basename "$script"` # Basename of the script progdir=`dirname "$script"` # Dirname of the script source "${progdir}/lib.bash" # Include default bash library PATH="$WORKPATH" # Set PATH to something useful # Presets raw=0 eopt="" number="" param="" filename="" # Loop until all parameters are used up while [ $# -gt 0 ]; do pname=${1} case "$1" in -f | --filename) shift if [ "$1" != "" ]; then filename="$1" if [ ! -r "$filename" ]; then errstr="Can't read filename '$filename'." fi shift else errstr="Please specify a filename after parameter '$pname'." fi ;; -n | --number) shift if [ "$1" != "" ]; then number="$1" # ToDo: Check if input is a number between 0 and xx shift else errstr="Please specify a number after parameter '$pname'." fi ;; -r | --raw) shift raw=1 ;; -v | --version) shift showversion=1 ;; -h | --help) shift showhelp=1 ;; -q | --quiet) shift eopt="$pname" ;; *) errstr="Unknown parameter: '$1'." shift esac done # Display help or error message DisplayHelp # Set defaults # Check if he have jq in path and right version jqversok=`check-version jq --min 1.5 | cut -d' ' -f3` if [ "$jqversok" != "ok" ]; then # At least jq version 1.5 is needed for 'first(inputs)', 'keys_unsorted' and 'nth(0)' errormsg $eopt 2 "($progstr) No 'jq' in '$PATH' or version is less than '1.5'." ClearSTDIN exit 2 else # Read from stdin or file if [ "$filename" != "" ]; then # Select only the first object (if there are more in input) / -n option required cat $filename | sed 's|//.*$||' | jq -M . > $scratchfile 2>&1 stat=$? else if [ ! -t 0 ]; then cat /dev/stdin | sed 's|//.*$||' | jq -M . > $scratchfile 2>&1 stat=$? else errormsg $eopt 3 "($progstr) No filename specified and stdin seems to be empty." exit 3 fi fi if [ $stat -gt 0 ]; then errrsn=`head -n 2 $scratchfile` errormsg $eopt 3 "($progstr) Tool 'jq' detected an error in JSON input." "$errrsn" filecheck -rm $scratchfile exit 3 else result=`filecheck -sl $scratchfile` if [ "$result" != "" ]; then # "data" is being used by "oci cli" and "result" is used by "opc cli" headstr=`head -n 2 $scratchfile | tr -d '\n' | tr -s ' '` if [ "$headstr" == '{ "data": [' -o "$headstr" == '{ "result": [' ]; then mv $scratchfile ${scratchfile}.cp cat ${scratchfile}.cp | jq -M .[] > $scratchfile if [ "$number" != "" ]; then headstr=`head -n 1 $scratchfile` if [ "$headstr" != "[" ]; then errormsg $eopt 5 "($progstr) JSON file doesn't contain records." filecheck -rm ${scratchfile}.cp filecheck -rm $scratchfile exit 5 else mv -f $scratchfile ${scratchfile}.cp cat ${scratchfile}.cp | jq -M 'nth('$number')' > $scratchfile result=`filecheck -sl $scratchfile` if [ "$result" == "" ]; then errormsg $eopt 6 "($progstr) JSON file doesn't contain specified record (number $number)." filecheck -rm ${scratchfile}.cp filecheck -rm $scratchfile exit 6 fi fi fi filecheck -rm ${scratchfile}.cp else if [ "$headstr" == '{ "data": {' -o "$headstr" == '{ "result": {' ]; then mv $scratchfile ${scratchfile}.cp cat ${scratchfile}.cp | jq -M .[] | grep -v '^"' > $scratchfile filecheck -rm ${scratchfile}.cp fi fi if [ $raw -eq 0 ]; then while IFS=':' read -r key value; do if [ "$key" != "" -a "$value" != "" ]; then key=`echo "$key" | sed 's|-\(.\)|\U\1|g'` printf "%s:%s\n" "$key" "$value" else printf "%s\n" "$key" fi done < $scratchfile else cat $scratchfile fi else errormsg $eopt 4 "($progstr) JSON file contains less then 2 lines." filecheck -rm $scratchfile exit 4 fi fi fi # Cleanup and exit Cleanup exit $exitcode