Pergunta

so I have a GET command retrieving data from a server, and only need specific parts of this info.

I have a working script but the awk part is very long and I was wondering if I could get some help shortening it.

Current script:

curl  --insecure -u $HMCUSER:$HMCPASS -H "Accept: */*" -H "Content-type: application/json" -s --header "X-API-Session:$COOKIE" -X GET https://$HMCIP:6794$BCID1/blades | awk -F\" '{print $50" M1:"$42"\n"$114" M1:"$106"\n"$18" M1:"$10"\n"$98" M1:"$90"\n"$34" M1:"$26"\n"$82" M1:"$74"\n"$66" M1:"$58"\n"$130" M1:"$122}' > ~walkers/blade-info-new

echo -e "\n`cat blade-info-new`\n"

and the output is:

/api/blades/394a7ea8-02d4-11e1-b71a-5cf3fcad1a40 M1:B.1.01

/api/blades/749f35cc-02d7-11e1-946a-5cf3fcad1ef8 M1:B.1.02

/api/blades/eeae9670-02d5-11e1-a5ee-5cf3fcad21e0 M1:B.1.03

/api/blades/3949f5a0-02d4-11e1-85df-5cf3fcad1dc8 M1:B.1.04

/api/blades/d25df328-02d3-11e1-a1e9-5cf3fcad2158 M1:B.1.05

/api/blades/bbecebd8-02d0-11e1-aca7-5cf3fcacf4a0 M1:B.1.06

/api/blades/3016b5d8-02d7-11e1-a66f-5cf3fcad1dd0 M1:B.1.07

/api/blades/75796586-02ea-11e1-8ab0-5cf3fcacf040 M1:B.1.08

(there are two columns: /api/blades/... and M1:B.1.0#)

So I tried this:

for i in {10..130..8}
do
     try=$(curl  --insecure -u $HMCUSER:$HMCPASS -H "Accept: */*" -H "Content-type: application/json" -s --header "X-API-Session:$COOKIE" -X GET https://$HMCIP:6794$BCID1/blades | awk -v i=$i -F\" '{print $i}')
     echo "$try"
done

hoping to get the same output as above and instead I just get the complete JSON object:

{"blades":[{"status":"operating","name":"B.1.03","type":"system-x","object-uri":"/api/blades/eeae9670-02d5-11e1-a5ee-5cf3fcad21e0"},{"status":"operating","name":"B.1.05","type":"system-x","object-uri":"/api/blades/d25df328-02d3-11e1-a1e9-5cf3fcad2158"},{"status":"operating","name":"B.1.01","type":"system-x","object-uri":"/api/blades/394a7ea8-02d4-11e1-b71a-5cf3fcad1a40"},{"status":"operating","name":"B.1.07","type":"system-x","object-uri":"/api/blades/3016b5d8-02d7-11e1-a66f-5cf3fcad1dd0"},{"status":"operating","name":"B.1.06","type":"system-x","object-uri":"/api/blades/bbecebd8-02d0-11e1-aca7-5cf3fcacf4a0"},{"status":"operating","name":"B.1.04","type":"system-x","object-uri":"/api/blades/3949f5a0-02d4-11e1-85df-5cf3fcad1dc8"},{"status":"operating","name":"B.1.02","type":"system-x","object-uri":"/api/blades/749f35cc-02d7-11e1-946a-5cf3fcad1ef8"},{"status":"operating","name":"B.1.08","type":"system-x","object-uri":"/api/blades/75796586-02ea-11e1-8ab0-5cf3fcacf040"}]}

So I was wondering how to get the variable to work? I've been on many websites and everyone seems to say awk -v i=$i should work...

EDIT: The sequence I want to print is the object uri (i.e. /api/blades/...) followed by the blade name (i.e. B.1.01). These infos are all in the JSON object returned by the curl command starting with the tenth field and every 8th field after that (using " as a delimiter):

{"blades":[{"status":"operating","name":"B.1.03","type":"system-x","object-uri":"/api/blades/eeae9670-02d5-11e1-a5ee-5cf3fcad21e0"},{"status":"operating","name":"B.1.05","type":"system-x","object-uri":"/api/blades/d25df328-02d3-11e1-a1e9-5cf3fcad2158"},{"status":"operating","name":"B.1.01","type":"system-x","object-uri":"/api/blades/394a7ea8-02d4-11e1-b71a-5cf3fcad1a40"},{"status":"operating","name":"B.1.07","type":"system-x","object-uri":"/api/blades/3016b5d8-02d7-11e1-a66f-5cf3fcad1dd0"},{"status":"operating","name":"B.1.06","type":"system-x","object-uri":"/api/blades/bbecebd8-02d0-11e1-aca7-5cf3fcacf4a0"},{"status":"operating","name":"B.1.04","type":"system-x","object-uri":"/api/blades/3949f5a0-02d4-11e1-85df-5cf3fcad1dc8"},{"status":"operating","name":"B.1.02","type":"system-x","object-uri":"/api/blades/749f35cc-02d7-11e1-946a-5cf3fcad1ef8"},{"status":"operating","name":"B.1.08","type":"system-x","object-uri":"/api/blades/75796586-02ea-11e1-8ab0-5cf3fcacf040"}]}

The blade names don't have to be in numerical order (B.1.01 to B.1.08), only on the same line as the corresponding ID

EDIT 2: Found a work around. Used a C type for loop instead of the normal bash: for (( i=10; i<=130; i+=8 )) instead of for i in {10..130..8}

Foi útil?

Solução 3

If I understand correctly you're wanting {10..130..8} to expand to give the required series of $i values.

In my version of bash (it's ooooold: 3.2.25) the string {10..130..8} doesn't expand to anything and so the loop is entered with i="{10..130..8}" and so awk uses ${10..130..8} which appears to simplify to $0 (i.e. the whole curl return string). Hence your problem. You can test if this is the case by putting echo $i inside your loop.

You need a better way of getting the series of values you want. You can use "seq" for this (man seq for more info). $( seq 10 8 130 ) should do it.

Further, you can make it so that curl is only called once with something messier like # Construct the string of fields for i in $( seq 10 8 130 ); do fields="$fields,\$$i" done fields=$( echo "$fields" | sed 's/^,//' ) # Remove the leading comma ...curl command... | awk '{print '$fields'}'

Outras dicas

The proper answer to this question is to ditch awk (even though I love awk) and use a real JSON parser, e.g. the very handy jq tool.

I think you want awk to access the updated value of the i variable. Because the awk instruction is between apostrophes (''), the value of i is hidden from awk, but you can avoid it by removing the apostrophes from the piece of the instruction that is replaced by the actual value of i. It is explained on this online AWK manual, in the section Dynamic Variables.

So for your particular case, you could try

awk -F\" '{print $'$i'}'

instead of

awk -v i=$i -F\" '{print $i}'

at the end of your pipeline command.

How about changing record separator (RS), and defining field separator to quote. Then save the name, and print it together with object-url. The command below should give you a starting point

curl [...] | awk -v RS=, -F\" '{
    if ($2 ~ /^name$/) {name=$4}
    if ($2 ~ /^object-uri$/) {print name, $4}
}'

p.s. Remote the if's and printing $0 if you want to see how the RS=, helps you.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top