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
    Feb 10 '14 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. Feb 10 '14 at 15:35
  • Yes they are actually in the data? OK, then everything in my answer except the awk one should work.
    – terdon
    Feb 10 '14 at 15:36
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 Feb 10 '14 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
    Feb 10 '14 at 16:13
  • 1
    Parsing with regexes is brittle. Feb 10 '14 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
    Feb 10 '14 at 16:28
  • Your answers will work for this one line, today. Next week, the line contains "accountHeader": {"a": "{boom}", ... Feb 10 '14 at 16:31

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.