简体   繁体   中英

Check values in JSON file array using jq

I'm a beginner and I'm trying to make a bash script that downloads data from a website and tells me hourly prices of a service and tells me when it is cheap and when it is expensive.

curl -s https://something.json | jq '.tomorrow[] | select(.region=="region3") | {values, median}'

From that command I get this:

{
  "values": [
    71.65,
    70.76,
    70.63,
    71.43,
    73.47,
    84.35,
    88.18,
    97.98,
    112.65,
    155.36,
    155.32,
    207.12,
    252.48,
    311.12,
    350.38,
    452.02,
    461.86,
    503.09,
    487.77,
    465.18,
    401.17,
    335.88,
    298.53,
    255.61
  ],
  "median": 243.08
}

and I want to check each value compared to the median and print out something like

At 1am it is cheap
...
At 5pm it is expensive
...
At 11pm it is cheap
...

I tried this, but it didn't work

curl -s https://something.json | jq '.tomorrow[] | select(.region=="region3") | {values, median} | if .values >= .median then "Expensive" elif .values <= .median then "Cheap"'

I thought about using walk() aswell but couldn't quite figure it out.

You can use to_entries which will use the array's index as key:

.median as $median
| .values
| to_entries[]
| "At \(.key+1) it is \(if .value >= $median then "expensive" else "cheap" end)"

You could also modify key and value before interpolating the string:

.median as $median
| .values
| to_entries[]
| .key += 1
| .value |= if . >= $median then "expensive" else "cheap" end
| "At \(.key) it is \(.value)"

I doubt that your data starts at 01:00 and ends at 00:00 (24:00), but if it did, here's how you would format it:

.median as $median
| .values
| to_entries[]
| .ampm = if (.key+1)%24 >= 12 then "pm" else "am" end
| .key %= 12
| .key += 1
| .value |= if . >= $median then "expensive" else "cheap" end
| "At \(.key)\(.ampm) it is \(.value)"

But I would assume at starts at 00:00 and ends at 23:00, which makes the code a lot simpler.

Output when running with jq -r ( --raw-output ):

At 1am it is cheap
At 2am it is cheap
At 3am it is cheap
At 4am it is cheap
At 5am it is cheap
At 6am it is cheap
At 7am it is cheap
At 8am it is cheap
At 9am it is cheap
At 10am it is cheap
At 11am it is cheap
At 12pm it is cheap
At 1pm it is expensive
At 2pm it is expensive
At 3pm it is expensive
At 4pm it is expensive
At 5pm it is expensive
At 6pm it is expensive
At 7pm it is expensive
At 8pm it is expensive
At 9pm it is expensive
At 10pm it is expensive
At 11pm it is expensive
At 12am it is expensive

Here's one way (assuming the first entry corresponds to 12am):

(.values | to_entries)[] as {$key, $value}
| "At \($key * 3600 | strftime("%l %P")) it is \(
    if $value < .median then "cheap" else "expensive" end
  )"
At 12 am it is cheap
At  1 am it is cheap
At  2 am it is cheap
At  3 am it is cheap
At  4 am it is cheap
At  5 am it is cheap
At  6 am it is cheap
At  7 am it is cheap
At  8 am it is cheap
At  9 am it is cheap
At 10 am it is cheap
At 11 am it is cheap
At 12 pm it is expensive
At  1 pm it is expensive
At  2 pm it is expensive
At  3 pm it is expensive
At  4 pm it is expensive
At  5 pm it is expensive
At  6 pm it is expensive
At  7 pm it is expensive
At  8 pm it is expensive
At  9 pm it is expensive
At 10 pm it is expensive
At 11 pm it is expensive

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM