3

Ubuntu 16.04

bash -version  
GNU bash, version 4.4.0(1)-release (x86_64-unknown-linux-gnu)

I would like to grep for 2 patterns and then have them listed side by side. At the moment, this is what I have:

root@tires ~ # grep -e tire_id -e appID /path/to/*/vehicle/production.json
/path/to/000001_000002/vehicle/production.json:    "tire_id": "1305436516186552",
/path/to/000001_000002/vehicle/production.json:        "appID": "1164562920689523",
/path/to/000001_000079/vehicle/production.json:    "tire_id": "1815123428733289",
/path/to/000001_000079/vehicle/production.json:        "appID": "18412365908966538",
/path/to/000001_000088/vehicle/production.json:    "tire_id": "138477888324",

This is what I would like to have although anything similar would work actually.

root@tires ~ # grep -e tire_id -e appID /path/to/*/vehicle/production.json
/path/to/000001_000002/vehicle/production.json:    tire_id: 1305436516186552, appID: 1164562920689523
/path/to/000001_000079/vehicle/production.json:    tire_id: 1815123428733289, appID: 18412365908966538

File example here:

{
    "socal": "https://xxx.xxxxx.xxx",
    "ip": "xxx.xxx.xxx.xxx",
    "tire_id": "213275925375485",
    "client": {
        "platform": "xx",
        "clientID": "xxxxx",
        "serviceID": "xxxxx",
        "service_id": XXXX,
        "vendor": "default"
    },
    "locale": "en_US",
    "cdc": {
        "appID": "233262274090443",
        "isdel": "ORdiZBMAQS2ZBCnTwZDZD",
    },
    "attachments": {
        "output": "attachments",
        "public": false,
    },
}
3
  • 4
    Looks like something more apt for jq than grep.
    – DopeGhoti
    Commented Jul 12, 2018 at 15:25
  • 1
    post a testable production.json contents Commented Jul 12, 2018 at 15:29
  • @RomanPerekhrest I posted an example, see OP.
    – Vituvo
    Commented Jul 12, 2018 at 16:07

4 Answers 4

12

The right way with jq tool for a valid JSON documents:

Sample file1.json:

{
    "socal": "https://xxx.xxxxx.xxx",
    "ip": "xxx.xxx.xxx.xxx",
    "tire_id": "213275925375485",
    "client": {
        "platform": "xx",
        "clientID": "xxxxx",
        "serviceID": "xxxxx",
        "service_id": "XXXX",
        "vendor": "default"
    },
    "locale": "en_US",
    "cdc": {
        "appID": "233262274090443",
        "isdel": "ORdiZBMAQS2ZBCnTwZDZD"
    },
    "attachments": {
        "output": "attachments",
        "public": false
    }
}

Sample file2.json:

{
    "socal": "https://xxx.xxxxx.xxx",
    "ip": "xxx.xxx.xxx.xxx",
    "tire_id": "1305436516186552",
    "client": {
        "platform": "xx",
        "clientID": "xxxxx",
        "serviceID": "xxxxx",
        "service_id": "XXXX",
        "vendor": "default"
    },
    "locale": "en_US",
    "cdc": {
        "appID": "1164562920689523",
        "isdel": "ORdiZBMAQS2ZBCnTwZDZD"
    },
    "attachments": {
        "output": "attachments",
        "public": false
    }
}

And the solution itself:

jq -r 'input_filename + " tire_id: \(.tire_id) appID: \(.cdc.appID)"' file*.json

The output:

file1.json tire_id: 213275925375485 appID: 233262274090443
file2.json tire_id: 1305436516186552 appID: 1164562920689523
1
  • Your answer is much simpler and efficient for what I needed.
    – Vituvo
    Commented Jul 12, 2018 at 17:40
1

You can do this with grep but it's rather conplicated and Roman's answer is actually better.

Your example contents are just from one file so there is only once instance of tire_id and appID.

Use this:

echo $(echo /path/to/production.json && egrep "tire_id|appID" /path/to/production.json | sed -e 's|"||g' | sed -e 's|,||2') && echo $(echo /path/to/production2.json && egrep "tire_id|appID" /path/to/production2.json ) | sed -e 's|"||g' | sed -e 's|,||2'

echo puts everything on the same line with command substitution.

egrep does the same thing as grep -e but allows you to put all the strings together separated by | instead of having to use -e string each time.

sed -e 's|"||g' removes the apostrophes.

sed -e 's|,||2 removes the comma from the end of the value for appID which is what is shown in your desired output.

Output:

/path/to/production.json tire_id: 213275925375485 appID: 233262274090443
/path/to/production2.json tire_id: 1815123428733289 appID: 18412365908966538

/path/to/production.json and /path/to/production2.json are just placeholders.

This obviously requires a lot of modification as you'd have to grep each file separately and use an echo command substitution for each one. I'm only including it if you insist upon using grep or if in the future, it's not a json file.

2
  • @Your answer is awesome and I learned a lot from it. Much appreciated. You are also right about Roman's answer. He uses the command made for the job, which I did not know existed. Hat's off to you mate.
    – Vituvo
    Commented Jul 12, 2018 at 17:40
  • 1
    @needtoknow No problem. Glad to help. Commented Jul 12, 2018 at 17:48
0

With a sed script :

grep -e tire_id -e appID /path/to/*/vehicle/production.json | sed -n '/\(.*:\)/h;n;s/.*n://;H;g;s/\n//;p'

Retrun

/path/to/000001_000002/vehicle/production.json:    "tire_id": "1305436516186552",        "appID": "1164562920689523",
/path/to/000001_000079/vehicle/production.json:    "tire_id": "1815123428733289",        "appID": "18412365908966538",
/path/to/000001_000088/vehicle/production.json:    "tire_id": "138477888324",

it works if each line "tire_id" is followed by a line "appID". Otherwise, you need a more complex sed script

2
  • This is also nice. Can you remove the apostrophes and commas.
    – Vituvo
    Commented Jul 12, 2018 at 20:01
  • sed -n 'h;n;s/.*n://;H;g;s/\n//;s/"//g;s/,//g;p'
    – alux
    Commented Jul 12, 2018 at 21:09
0

This command will work even if in a file it misses a "tire_id" or "appID" line. It will not be displayed :

grep -e tire_id -e appID /path/to/*/vehicle/production.json | sed -n 's/\(tire_id\)/\1/;T;h;n;s/.*n:.*\(appID\)/\1/;T;H;g;s/\n/ /;s/"//g;s/,//g;p'
1
  • Very cool mate. I learned a lot from it.
    – Vituvo
    Commented Jul 12, 2018 at 22:22

You must log in to answer this question.

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