2

I have a string given below. I just need to get the first accountHeader (bolded) JSON string.

<START AdditionalInfo#:>[FormsGenerationServiceImpl::,  accountNumber:ABC07667 ,  [Source System Request  : {"Info":{"Holder": {"nameData": {"shortName": "McIntosh"}},**"accountHeader": {"a": "Y","b": "1","c": "4","draft": "P","e": "Y0000DU9","f": "T","g": "1"}**,"forms": {"maskSSN": "N","deliverForms": "G","selectedForms": {"T5": ["F10"],"T1": ["F1403"],"T2": ["F100001401"]}},"accountHeader": {"a": "Y","b": "1","c": "4","d": "HWA","draftRequestType": "P","e": "Y0000DU9","f": "T","g": "1"}}} ], null]<AdditionalInfo#: END>

My output should be

"accountHeader": {"a": "Y","b": "1","c": "4","draft": "P","e": "Y0000DU9","f": "T","g": "1"}
3
  • Are the ** actually in the data or are you using them to highlight the part you're interested in?
    – terdon
    Commented Feb 10, 2014 at 15:24
  • Yes, Terdon.. And if you notice that there are two accountheader field. I am interested in the first one. If I get that, I can easily the parse the JSON related to the field. Commented Feb 10, 2014 at 15:35
  • Yes they are actually in the data? OK, then everything in my answer except the awk one should work.
    – terdon
    Commented Feb 10, 2014 at 15:36

1 Answer 1

1

Here are a few options:

  1. Use grep with the -o flag to print only the matching part of the line and filter with head to get the first match only:

    grep -o '"accountHeader[^}]*}' file.json | head -n1 
    

    The regular expression looks for a "accountHeader then as many as possible non-} characters until the first }. It's basically the same regex used in the other solutions below as well.

  2. Use sed with -n to suppress printing and p after the substitution to print only if the substitution was a success. Then, substitute (remove) everything but what you want:

    sed -n  's/.*\("accountHeader[^}]*}\).*/\1/p' file.json 
    
  3. Use Perl, the -l adds a newline to each print call, the -n means "process each line of the input file" and apply the script given by -e:

    perl -lne  '/.*("accountHeader[^}]*})/ && print $1' file.json 
    
  4. Use awk, this assumes that the ** in your example input are there to highlight the part you're interested in and don't actually exists in the real data. If so, this should work:

    awk -F'},' '{print $2"}"}' file.json
    

If the ** are actually there, things are even simpler, just use them as field delimiters:

awk -F'**' '{print $2"}"}' file.json

or

perl -F"\*\*" -alne 'print $F[1]' file.json
13
  • 1) these are the available pattern for grep - -hblcnsviw Commented Feb 10, 2014 at 16:09
  • @ahamedirshad123 1) you mean you have no -o? What operating system are you using? I guess OSX since that lacks the -o. Please remember to mention your OS in your questions. 2) The sed works fine using the example you posted (at least on my system) but there might be a difference on OSX. The perl one should be the most portable. Does that work?
    – terdon
    Commented Feb 10, 2014 at 16:13
  • 1
    Parsing with regexes is brittle. Commented Feb 10, 2014 at 16:25
  • @WarrenYoung 1) this is not [XH]TML, the opening and closing tags are irrelevant 2) this is a single line, implementing a whole script with a language parser seems a little overkill don't you think? 3) There is a huge difference between parsing an entire file containing structured data and extracting only a single pattern from it. Regex is the perfect tool for this, what kind of language parser would you suggest for what the OP wants?
    – terdon
    Commented Feb 10, 2014 at 16:28
  • Your answers will work for this one line, today. Next week, the line contains "accountHeader": {"a": "{boom}", ... Commented Feb 10, 2014 at 16:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .