Home > Mobile >  the string length of jq output is wrong, and it is impossible to compare
the string length of jq output is wrong, and it is impossible to compare

Time:11-29

i dont get this problem... maybe someone can help me out :)

i have a Jsonfile and i read out strings and put it into variables. if i compare these after the loop they never are the same.. the outputs of jq have a hidden charakter or so..

Examplecode:

while read -r id
do      
    read -r hostname
    for server in "$serverlist"
    do
        if [[ "$hostname" == "$server" ]]; then
            echo "$hostname"
            echo "$server"
        else
            errorser[$i]=$server
            i=$((i 1))
        fi
    done
done < <(jq -r '.[] | .id, .serverinfos.hostname | @text' $jsonlist)

serverlist is a array with strings of hostnames like "flowmox". If i do a simple size on the string which came out if the jq it shows for the text "flowmox" 8 but it is 7... cutting is also not possible

        echo size=${#hostname} 
        hostname="${hostname##*( )}"
        echo size=${#hostname}
        echo size="flowmox" 

Result:

8
8
7

added part of the jsonfile:

[
{
    "id":1,
    "childofid":null,
    "parentofids":[null],
    "infosupdatedat":"2021-11-27",
    "serverinfos":{
        "hostname":"flowmox",
        "description":"Proxmox - Host for vm's and more",
        "status":"ready",
        "servertype":"physisch",
        "category":"vm-host",
        "productname":"ProLiant DL380 G7",
        "Model":"589150-421",
        "Serialnumber":"",
        "managementtype":"ILO3"
    },

. . .

CodePudding user response:

This seems a behavior of jq with the raw output. each result is in a new line.

read here: https://github.com/stedolan/jq/issues/787

Actually, in 1.5 it's already the case that you can use -j to stop newlines being printed, but it does put jq into raw-output mode.

unfortunately it doesnt solve the problem for me. i need to cut the last charakter out...

maybe "hostname=echo $hostname | tr -d '\n'" is a solution for me

CodePudding user response:

The following should work for you :

tr -d $'\r' "$jsonList"
while read -r id; do
    #[...]
done < <(jq -r '.[] | .id, .serverinfos.hostname | @text' "$jsonlist")

CodePudding user response:

Instead of @text you should use @tsv, which is easy to parse and unescape with the shell:

#!/bin/bash

jsonlist=( file1.json file2.json )
serverlist=( flowmox streamox )

while IFS=$'\t' read -r id hostname
do
    # unescaping (not needed in your case)
#   printf -v id '%b' "$id"
#   printf -v hostname '%b' "$hostname"

    for server in "${serverlist[@]}"
    do
        # [...]
    done
done < <(jq -r '.[] | [ .id, .serverinfos.hostname ] | @tsv' "${jsonlist[@]}")

remarks:

  • You say that "serverlist is a array with strings of hostnames", if that's the case then you're using it wrong in for server in "$serverlist", which should be for server in "${serverlist[@]}"

  • Also, you're using an unquoted $jsonlist; you should put your JSON files in an array instead of a string, and use "${jsonlist[@]}"

  • Related