0

I have an array like below. I want to parse entire data to my bash array. So i can call the first "JSON addressLineOne" from ${bashaddr[0]}, and etc.

[
{
"id":"f0c546d5-0ce4-55ee-e043-516e0f0afdc1",
"cardType":"WMUSGESTORECARD",
"lastFour":"1682",
"cardExpiryDate":"2012-01-16",
"firstName":"robert",
"lastName":"robishaw",
"addressLineOne":"Apt venue",
"addressLineTwo":"",
"city":"oakdale",
"state":"CT",
"postalCode":"06370",
"phone":"534534",
"isDefault":false
},
{
"id":"f0c546d5-0ce0-55ee-e043-516e0f0afdc1",
"cardType":"MASTERCARD",
"lastFour":"2731",
"cardExpiryDate":"2009-08-31",
"firstName":"robert",
"lastName":"robishaw",
"addressLineOne":"119 maple ave.",
"addressLineTwo":"",
"city":"uncasville",
"state":"CT",
"postalCode":"06382",
"phone":"7676456",
"isDefault":false
},
{
"id":"f0c546d5-0ce2-55ee-e043-516e0f0afdc1",
"cardType":"MASTERCARD",
"lastFour":"6025",
"cardExpiryDate":"2011-08-31",
"firstName":"robert",
"lastName":"robishaw",
"addressLineOne":"Angeline Street",
"addressLineTwo":"",
"city":"oakdale",
"state":"CT",
"postalCode":"06370",
"phone":"7867876",
"isDefault":false
}

]

I have tried like this:

#!/bin/bash
addressLineOne="$(echo $card | jsawk 'return this.addressLineOne')"

but it gives me the entire address:

["address 1","address 2","address 3"]

Thank you.

  • Bash doesn't even have multidimensional array. – 4ae1e1 Jan 08 '16 at 07:37
  • so i can't do that ? – Ahmad Malhadi Jan 08 '16 at 07:41
  • I don't know what you want to do exactly. "I want to parse entire data to my bash array." No, not in parsed form — bash array elements must be scalars, while you want them to be associative arrays. "So i can call the first "JSON addressLineOne" from ${bashaddr[0]}, and etc." This sentence is not very understanable. "I have tried like this:" That has nothing to do with multidimensional array, so I'm not sure what you want now. – 4ae1e1 Jan 08 '16 at 07:53
  • oh.. sorry for my bad english. i just want to get the first addressLineOne value. Not all of the value – Ahmad Malhadi Jan 08 '16 at 07:55
  • i tried this: `addressLineOne="$(echo $card | jsawk 'return his[0].addressLineOne')"` – Ahmad Malhadi Jan 08 '16 at 07:58
  • Okay, I've never used `jsawk` before, but I just read the manual and played with it for a short while, and decided that it's not for you. `jsawk` is designed to map an array to an array, and the output is JSON; whereas you want to extract a single raw string. Of course you could do something hackish, e.g., wrapping the whole array in a singleton array: `echo "[$card]" | jsawk 'return this[0].addressLineOne'`, which gets you to `["Apt venue"]`, but now what? Manually decode a JSON string? No. – 4ae1e1 Jan 08 '16 at 08:21
  • 1
    What you should use instead is jq: https://github.com/stedolan/jq. `echo "$card" | jq -r '.[0].addressLineOne'`. Output: `Apt venue`. More concise, no bullshit, gets you exactly what you want. – 4ae1e1 Jan 08 '16 at 08:22
  • (A little more about jsawk: it's basically wrapping your code with some Javascript boilerplate, which is somewhat similar to Perl's `-p` switch; you're still writing Javascript, just a lot less Javascript. Meanwhile, jq defines a completely new DSL, which is very concise and powerful.) – 4ae1e1 Jan 08 '16 at 08:26
  • ohh.. great. I will try it later. :D Thanks for your help. – Ahmad Malhadi Jan 08 '16 at 09:11

2 Answers2

1

I wrote the answer below before reading the comments, but this is exactly the same answer as @4ae1e1 provided, except I don't put -r tag in case you want the values to remain quoted (e.g. passing this as an argument somewhere else).

I know this is not jsawk, but do consider jq:

jq '.[].addressLineOne' yourfile.txt

And to access specific values you can put record number in the square brackets (starting with 0 for the first address and so on). For example to get the address for the third record:

jq '.[2].addressLineOne' yourfile.txt

For learning more about jq and advanced uses, check: http://jqplay.org

econ
  • 547
  • 7
  • 22
0

What you need to do is make use of the -a switch to apply some post processing and filter the output array like this: jsawk 'return this.addressLineOne' -a 'return this[0]' From the documentation:

-b <script> | -a <script>
      Run the specified snippet of JavaScript before (-b) or after (-a)
      processing JSON input. The `this` object is set to the whole JSON
      array or object. This is used to preprocess (-b) or postprocess
      (-a) the JSON array before or after the main script is applied.
      This option can be specified multiple times to define multiple
      before/after scripts, which will be applied in the order they
      appeared on the command line.
Phillmac
  • 109
  • 7