I get the contents of a text file into an array and then sequentially get the elements of the array and try to add the elements to the json:
#!/bin/bash
JSON=$(jq -n '')
readarray -t array < ./station.sample
count=0
for e in "${array[@]}"
do
if echo "$e" | grep -Eq '^[0-9]{10}' >/dev/null
then
timestamp=$e
datetime=`date +'%Y-%m-%d %H:%M:%S' -d "@$e"`
JSON=$(echo $JSON | jq --arg timestamp "${timestamp}" '. += $ARGS.named')
JSON=$(echo $JSON | jq --arg datetime "${datetime}" '. += $ARGS.named')
fi
if echo "$e" | grep '^Station ' >/dev/null
then
NODE=$(jq -n '')
mac=`echo "$e" | awk '{ print $2 }'`
interface=`echo "$e" | awk '{ print $4 }' | rev | cut -c2- | rev`
JSON=$(echo $JSON | jq --argjson nodes "[]" '. += $ARGS.named')
JSON=$(echo $JSON | jq --arg mac "${mac}" --arg count "${count}" '.nodes[0] += {"mac": $mac}')
JSON=$(echo $JSON | jq --arg interface "${interface}" '.nodes[0] += {"interface": $interface}')
count=$((count+1))
fi
done
As a result, I get a json like this:
{
"timestamp": "1721396365",
"datetime": "2024-07-19 16:39:25",
"nodes": [
{
"mac": "14:88:00:00:00:06"
}
]
}
But I need to add multiple objects to the list, so I set a count variable and want to use it to specify the index of the list:
JSON=$(echo $JSON | jq --arg mac "${mac}" --arg count "${count}" '.nodes[$count] += {"mac": $mac}')
But in this variant adding list items doesn’t work.
How can I dynamically specify the index of the list?
I’ve tried all the options that came to mind, but I haven’t found a solution yet:
NODE=$(echo $NODE | jq --arg mac "$mac" '. += $ARGS.named')
NODE=$(echo $NODE | jq --arg interface "${interface}" '. += $ARGS.named')
JSON=$(echo $JSON | jq --argjson node "${NODE}" '.nodes[.nodes | length] = $ARGS.named')
It is necessary to use a variable to specify the index of the list.
2
Answers
That’s because when you use += for arrays, the RHS must be an array, like so:
By the way, I suspect you could greatly simplify things by using jq to do all (or at least nearly all) the required manipulations, thus avoiding the bash/awk/grep messiness.
It was interesting to deep dive into jq scripting, and here it is.
There is no clue as to what the input is and what the desired output is, so here are my assumptions:
Station
(nodes), and other ignored lines.Simple input generator:
The result for test input above:
Here is jq filter, save this into
filter.jq
:This filter should be run with the
-Rn
flags, e.g.: