1

I have a file similar to such.

SampleOutput

{

   "1": {

      "state": "RUNNING",

      "stats": {

         "name": "some-file",

         "uris": [

            "some-example.com"

         ],

         "host": "127.0.0.1",

         "port": 8080,

         "uptime": 168,

         "mem_quota": 2147483648,

         "disk_quota": 2147483648,

         "fds_quota": 16384,

         "usage": {

            "time": "2016-09-13 07:39:40 +0000",

            "cpu": 0.30315522606369516,

            "mem": 1069568000,

            "disk": 237203456

         }

      }

   },

   "0": {

      "state": "RUNNING",

      "stats": {

         "name": "some-file2",

         "uris": [

            "some-example-e.com"

         ],

         "host": "127.0.0.2",

         "port": 8081,

         "uptime": 169,

         "mem_quota": 2147483648,

         "disk_quota": 2147483648,

         "fds_quota": 16384,

         "usage": {

            "time": "2016-09-13 07:39:40 +0000",

            "cpu": 0.3086296386531593,

            "mem": 1073180672,

            "disk": 237203456

         }

      }

   },

   "2": {

      "state": "RUNNING",

      "stats": {

         "name": "some-file3",

         "uris": [

            "some-example.com"

         ],

         "host": "127.1.20.3",

         "port": 8190,

         "uptime": 168,

         "mem_quota": 2147483648,

         "disk_quota": 2147483648,

         "fds_quota": 16384,

         "usage": {

            "time": "2016-09-13 07:39:40 +0000",

            "cpu": 0.31213565359044587,

            "mem": 1072861184,

            "disk": 237203456

         }

      }

   }

}

And I require to extract the values of the cpu, mem and disk and put it in a file in format as so

0.30315522606369516,1069568000,237203456,0.3086296386531593,1073180672

Basically, it should be

first_instance_cpu,first_instance_mem,first_instance_disk,second_instance_cpu,second_instance_mem...

I hope you get the point.

I'm using the following grep statement to retrieve these values.

grep -Eow '"(cpu|mem|disk)": [0-9.]+' SampleOutput | grep '[0-9.]'

And this gives me output as follows

"cpu": 0.30315522606369516
"mem": 1069568000
"disk": 237203456
"cpu": 0.3086296386531593
"mem": 1073180672
"disk": 237203456
"cpu": 0.31213565359044587
"mem": 1072861184
"disk": 237203456

With the numbers I want highlighted in red (matching). Now, I want only the numbers but when I use the -o option with my second grep command, I get the numbers, sure, but each on a different line like so

0
.
3
3
1

..and so on.

How do I get the results as atleast whole numbers on different lines? Then I could use tr or something to comma separate them.

3
$ grep -Po '"(cpu|mem|disk)": \K[\d.]+' SampleOutput | paste -sd , -
0.30315522606369516,1069568000,237203456,0.3086296386531593,1073180672,237203456,0.31213565359044587,1072861184,237203456

grep implementations that support -o generally also support -P for PCRE where \K (in PCRE Version 7.2 19-Jun-07 or above) can be used to reset the start of the matching text (so grep -o only outputs what's matched on the right of it).

You were not far in your approach, you just had to replace grep -o '[0-9.]' with grep -oE '[0-9.]+', that is find sequences of one or more digits or dot instead of just one digit or dot.

6

Since your file is in JSON format I'll use jq:

jq '
    flatten |
    map(.stats.usage | del(.time)) |
    map([.cpu, .mem, .disk]) |
    flatten |
    .[]' <file.json | \
paste -sd ,

Output:

0.30315522606369516,1069568000,237203456,0.3086296386531593,1073180672,237203456,0.31213565359044587,1072861184,237203456

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.