1

my json file looks something like this

[{"product":"Apple","id":"2134"},{"product":"Mango","id":"4567"}]

I want to grep/sed/awk 'id' for given 'product'.

Output:

Enter product : Apple
Your product id is : 2134
  • 1
    You'd be better off using ruby or python and importing a json library than using bash for this. Ruby/python will parse the json file for you and make the data accessible. – Centimane Feb 3 '16 at 13:46
  • 3
    Sounds like a job for jq – don_crissti Feb 3 '16 at 13:47
1

sed is clumsy, but here is what I could get -

sed  's/.*\(Apple\)[^:]*:"\([0-9]*\)".*/Enter product ID: \1\nYour  product ID is: \2/' 3
Enter product ID: Apple
Your product ID is: 2134

sed  's/.*\(Mango\)[^:]*:"\([0-9]*\)".*/Enter product ID: \1\nYour product ID is: \2/' 3
Enter product ID: Mango
Your product ID is: 4567

Edited based on latest input which is slightly different

./prod.sed Apple
Enter product ID: Apple
Your product ID is: 1234

./prod.sed Mango
Enter product ID: Mango
Your product ID is: 12345

prod.sed (use 3rd line for publishName)

#sed  's/.*product_id":"\(Apple\).*"productBuildId":"\([0-9]*\)".*/Enter product ID: \1\nYour product ID is: \2/' data
sed  's/.*product_id":"\('"$1"'\).*"productBuildId":"\([0-9]*\)".*/Enter product ID: \1\nYour product ID is: \2/' data
sed  's/.*product_id":"\('"$1"'\)","publishName":"\([^"]*\)".*/Enter product ID: \1\nYour publish ID is: \2/' data

explanation : substitute the string <anything> Mango <anything other than :> : <number> with -> Your product ID is: Mango <next line> 
Your product ID is : <the number we got> 

 \1 and \2 save the matched expression in \(..\) for later use.
  • I checked with my text file, the sed command here is not working, its displaying whole of file. Can you explain me on this command? – Srikanth Yadake Feb 4 '16 at 8:09
  • Added explanation. Do you have separate lines in the file or all in 1 line ? – jai_s Feb 4 '16 at 8:49
  • I have all in 1 line. – Srikanth Yadake Feb 4 '16 at 9:11
  • how do I execute this? should I just enter the whole thing in the prompt? if so its not working. – Srikanth Yadake Feb 4 '16 at 9:12
  • yes. Could you put the input file somewhere (pastebin maybe?) and put the link here. – jai_s Feb 4 '16 at 9:20
6

Use a JSON aware tool. Perl has the JSON library:

#!/usr/bin/perl
use warnings;
use strict;

use JSON;

my $json = '[{"product":"Apple","id":"2134"},{"product":"Mango","id":"4567"}]';

print 'Enter product: ';
chomp( my $product = <> );

print 'Your product id is: ', 
    (grep $_->{product} eq 'Apple', @{ from_json($json) })[0]{id}, "\n";
  • 1
    thanks for this answer. But I am putting this in a .sh file. – Srikanth Yadake Feb 4 '16 at 9:20
  • 1
    perl -MJSON -e 'print map { $_ -> {id} } grep { $_ -> {product} eq "Apple" } @{decode_json( do { local $/; <> } )};' - if you really must use shell. But honestly? perl can do everything a shell script can, and SO MUCH more. – Sobrique Feb 4 '16 at 10:17
2

Use a json parser, not sed/grep/awk.

Using Python json module:

#!/usr/bin/env python2
import json
with open('file.json') as f:
    f_json = json.load(f)
    print 'Enter product : ' + f_json[0]['product'] + '\nYour product id is : ' + f_json[0]['id']

Output:

Enter product : Apple
Your product id is : 2134
  • thanks for this answer. I need to put this in a .sh file. and I dont use any modules – Srikanth Yadake Feb 4 '16 at 9:23
2

I created a file called json that looks like this:

[{"product":"Apple","id":"2134"},{"product":"Mango","id":"4567"},{"product":"Pear","id":"1111"},{"product":"Banana","id":"2222"}]

Then I run this on the command line:

 cat json | sed -e 's/.\?{"product"\:\"\([^\"]\+\)\","id"\:\"\([[:digit:]]\+\)[^}]}\+.\?/Enter Product : \1\nYour Product id is : \2\n/mgi'

The output is this:

Enter Product : Apple
Your Product id is : 2134
Enter Product : Mango
Your Product id is : 4567
Enter Product : Pear
Your Product id is : 1111
Enter Product : Banana
Your Product id is : 2222
  • thanks for this answer. As I see 'id' is made for number only. Can you show me how we can change this for something like below – Srikanth Yadake Feb 4 '16 at 12:05
  • [{"product_id":"Apple","publishName":"Fruit_01","productBuildId":"1234","revisio‌​n":1,"platform":"Linux"}],[{"product_id":"Mango","publishName":"Fruit_02","produc‌​tBuildId":"12345","revision":1,"platform":"Linux"}] I want to fetch "publishName" for say product_id "Apple" – Srikanth Yadake Feb 4 '16 at 12:05
  • change [[:digit:]] to [[:alpha:][:digit:]] – NiteRain May 6 '16 at 6:41
  • Also for you json string, it is pretty much the same thing, you just have to add for the extra attributes. – NiteRain May 6 '16 at 6:42
0

Given your input, the following sed command ...

sed -e 's/[}"]*\(.\)[{"]*/\1/g;y/,/\n/' <your_input

...will write to output...

[product:Apple
id:2134
product:Mango
id:4567]

...probably you can take it from there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.