Parse du result using sed

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
2
down vote

favorite












Hello i am trying to parse the result of du command but i don't know how to do it without looping
i execute the below command



du -shm /var/vmail/mailboxes/domain/*/mail


my result is a list e.g.:



80 /var/vmail/mailboxes/domain/USER1/mail 
150 /var/vmail/mailboxes/domain/USER2/mail
220 /var/vmail/mailboxes/domain/USER3/mail


The above list i want to transform it to json object with the below:



USER1: 80, USER2:150, USER3:220 


or at least to have something:



80 USER1
150 USER2
220 USER3


I tried with sed -e but without success, any ideas?







share|improve this question





















  • Show what you tried.
    – glenn jackman
    May 3 at 15:06














up vote
2
down vote

favorite












Hello i am trying to parse the result of du command but i don't know how to do it without looping
i execute the below command



du -shm /var/vmail/mailboxes/domain/*/mail


my result is a list e.g.:



80 /var/vmail/mailboxes/domain/USER1/mail 
150 /var/vmail/mailboxes/domain/USER2/mail
220 /var/vmail/mailboxes/domain/USER3/mail


The above list i want to transform it to json object with the below:



USER1: 80, USER2:150, USER3:220 


or at least to have something:



80 USER1
150 USER2
220 USER3


I tried with sed -e but without success, any ideas?







share|improve this question





















  • Show what you tried.
    – glenn jackman
    May 3 at 15:06












up vote
2
down vote

favorite









up vote
2
down vote

favorite











Hello i am trying to parse the result of du command but i don't know how to do it without looping
i execute the below command



du -shm /var/vmail/mailboxes/domain/*/mail


my result is a list e.g.:



80 /var/vmail/mailboxes/domain/USER1/mail 
150 /var/vmail/mailboxes/domain/USER2/mail
220 /var/vmail/mailboxes/domain/USER3/mail


The above list i want to transform it to json object with the below:



USER1: 80, USER2:150, USER3:220 


or at least to have something:



80 USER1
150 USER2
220 USER3


I tried with sed -e but without success, any ideas?







share|improve this question













Hello i am trying to parse the result of du command but i don't know how to do it without looping
i execute the below command



du -shm /var/vmail/mailboxes/domain/*/mail


my result is a list e.g.:



80 /var/vmail/mailboxes/domain/USER1/mail 
150 /var/vmail/mailboxes/domain/USER2/mail
220 /var/vmail/mailboxes/domain/USER3/mail


The above list i want to transform it to json object with the below:



USER1: 80, USER2:150, USER3:220 


or at least to have something:



80 USER1
150 USER2
220 USER3


I tried with sed -e but without success, any ideas?









share|improve this question












share|improve this question




share|improve this question








edited May 3 at 15:38









Thor

11k13256




11k13256









asked May 3 at 14:34









user1521944

132




132











  • Show what you tried.
    – glenn jackman
    May 3 at 15:06
















  • Show what you tried.
    – glenn jackman
    May 3 at 15:06















Show what you tried.
– glenn jackman
May 3 at 15:06




Show what you tried.
– glenn jackman
May 3 at 15:06










5 Answers
5






active

oldest

votes

















up vote
2
down vote



accepted










du -shm /var/vmail/mailboxes/domain/*/mail | awk -F '[ /]' ' print $1, $7 '


With the input from du in the format that you give, this would produce



80 USER1
150 USER2
220 USER3


The awk program simply picks out the appropriate fields from the output of du. It interprets each line as fields delimited by either spaces or slashes.



awk -F '[ /]' ' print $1, $(NF - 1) ' would also work.



To get this into JSON, using jq:



du -shm /var/vmail/mailboxes/domain/*/mail |
awk -F '[ /]' ' print $1, $7 ' |
jq -sR 'split("n")[0:-1] | map(split(" ")) | map((.[1]):.[0]) | add'


This would produce




"USER1": "80",
"USER2": "150",
"USER3": "220"




The jq expression first splits the input into separate array elements (one per line of input), and then splits these again on spaces into subarrays. At this point we have



[
[
"80",
"USER1"
],
[
"150",
"USER2"
],
[
"220",
"USER3"
]
]


After that, objects are created with the second element in each subarray as the key and the first as the value:



[

"USER1": "80"
,

"USER2": "150"
,

"USER3": "220"

]


The add at the end gives us the final result.






share|improve this answer






























    up vote
    3
    down vote













    try



    du -sm /var/vmail/mailboxes/domain/*/mail |
    sed 's:/var/vmail/mailboxes/domain/::; s:/mail::'


    where




    • s:/mail:: will replace /mail by nothing

    to go to json



    du -sm /var/vmail/mailboxes/domain/*/mail |
    sed 's:/var/vmail/mailboxes/domain/::; s:/mail::' |
    awk 'BEGIN sep="" ; printf "%s "%s":%s",sep,$2,$1; sep="," END printf "n"'





    share|improve this answer























    • JSON requires keys to be double-quoted strings. Changing the printf statement to printf "%s "%s":%s",sep,$2,$1; is enough to make this generate valid JSON.
      – Tim Kennedy
      May 3 at 14:55

















    up vote
    2
    down vote













    You can use awk to convert to 2-column format:



    $ du -shm | awk -F/ 'print $1" "$(NF - 1)'
    80 USER1
    150 USER2
    220 USER3


    For JSON, try:



    $ du -shm | awk -F/ 'print """$(NF - 1)"":"$1' | paste -sd, | printf "$(cat)" | jq

    "USER1": 80,
    "USER2": 150,
    "USER3": 220






    share|improve this answer






























      up vote
      1
      down vote













      jq does pretty well with raw-text, i.e. the -R flag, e.g.:



      du -sm /var/vmail/mailboxes/domain/*/mail |
      jq -R '
      split(" ") |
      .[0] as $size | # Remember size
      .[1] | split("/") | .[-2] as $name | # Extract username
      ($name) : ($size) # Compose object
      '


      Gives you:




      "USER1": "80"


      "USER2": "150"


      "USER3": "220"



      To merge the objects, use a second jq invocation:



      ... | jq -s add


      Output:




      "USER1": "80",
      "USER2": "150",
      "USER3": "220"



      Or in compact mode:



      ... | jq -sc add


      Output:



      "USER1":"80","USER2":"150","USER3":"220"





      share|improve this answer























      • Why use a second invocation of jq when you could just tack add on to the end of the first jq pipeline?
        – Kusalananda
        May 3 at 16:05










      • @Kusalananda: it wraps every object then
        – Thor
        May 3 at 16:07










      • Ah, because they are not in an array.
        – Kusalananda
        May 3 at 16:20










      • on this solution i receive the below error jq: error (at <stdin>:1): split input and separator must be strings
        – user1521944
        May 4 at 5:49











      • @user1521944: are you using jq version1.5?
        – Thor
        May 4 at 8:56

















      up vote
      1
      down vote













      This is a bit tricky to do with sed. However, here is a commented suggestion that works with GNU sed:



      parse.sed



      s|([^ ]+) .*/([^/]+)/.*| "2" : 1,| # Extract size and name in json-format
      1h; 1!H # Correctly add them to hold-space
      $
      z # Clear pattern-space
      s/^// # Prepend start-curly-brace
      G # Fetch formatted json from hold-space
      s/,$// # Remove last comma
      s/$/n/ # Append end-curly-brace
      p # Print



      Run it like this:



      du -shm /var/vmail/mailboxes/domain/*/mail | sed -Enf parse.sed


      Or as a one-liner:



      du -shm /var/vmail/mailboxes/domain/*/mail |
      sed -Ene 's|([^ ]+) .*/([^/]+)/.*| "2" : 1,|;1h;1!H;$z;s/^//;G;s/,$//;s/$/n/;p'


      Output in both cases:




      "USER1" : 80,
      "USER2" : 150,
      "USER3" : 220






      share|improve this answer























        Your Answer







        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "106"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        convertImagesToLinks: false,
        noModals: false,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );








         

        draft saved


        draft discarded


















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f441568%2fparse-du-result-using-sed%23new-answer', 'question_page');

        );

        Post as a guest






























        5 Answers
        5






        active

        oldest

        votes








        5 Answers
        5






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes








        up vote
        2
        down vote



        accepted










        du -shm /var/vmail/mailboxes/domain/*/mail | awk -F '[ /]' ' print $1, $7 '


        With the input from du in the format that you give, this would produce



        80 USER1
        150 USER2
        220 USER3


        The awk program simply picks out the appropriate fields from the output of du. It interprets each line as fields delimited by either spaces or slashes.



        awk -F '[ /]' ' print $1, $(NF - 1) ' would also work.



        To get this into JSON, using jq:



        du -shm /var/vmail/mailboxes/domain/*/mail |
        awk -F '[ /]' ' print $1, $7 ' |
        jq -sR 'split("n")[0:-1] | map(split(" ")) | map((.[1]):.[0]) | add'


        This would produce




        "USER1": "80",
        "USER2": "150",
        "USER3": "220"




        The jq expression first splits the input into separate array elements (one per line of input), and then splits these again on spaces into subarrays. At this point we have



        [
        [
        "80",
        "USER1"
        ],
        [
        "150",
        "USER2"
        ],
        [
        "220",
        "USER3"
        ]
        ]


        After that, objects are created with the second element in each subarray as the key and the first as the value:



        [

        "USER1": "80"
        ,

        "USER2": "150"
        ,

        "USER3": "220"

        ]


        The add at the end gives us the final result.






        share|improve this answer



























          up vote
          2
          down vote



          accepted










          du -shm /var/vmail/mailboxes/domain/*/mail | awk -F '[ /]' ' print $1, $7 '


          With the input from du in the format that you give, this would produce



          80 USER1
          150 USER2
          220 USER3


          The awk program simply picks out the appropriate fields from the output of du. It interprets each line as fields delimited by either spaces or slashes.



          awk -F '[ /]' ' print $1, $(NF - 1) ' would also work.



          To get this into JSON, using jq:



          du -shm /var/vmail/mailboxes/domain/*/mail |
          awk -F '[ /]' ' print $1, $7 ' |
          jq -sR 'split("n")[0:-1] | map(split(" ")) | map((.[1]):.[0]) | add'


          This would produce




          "USER1": "80",
          "USER2": "150",
          "USER3": "220"




          The jq expression first splits the input into separate array elements (one per line of input), and then splits these again on spaces into subarrays. At this point we have



          [
          [
          "80",
          "USER1"
          ],
          [
          "150",
          "USER2"
          ],
          [
          "220",
          "USER3"
          ]
          ]


          After that, objects are created with the second element in each subarray as the key and the first as the value:



          [

          "USER1": "80"
          ,

          "USER2": "150"
          ,

          "USER3": "220"

          ]


          The add at the end gives us the final result.






          share|improve this answer

























            up vote
            2
            down vote



            accepted







            up vote
            2
            down vote



            accepted






            du -shm /var/vmail/mailboxes/domain/*/mail | awk -F '[ /]' ' print $1, $7 '


            With the input from du in the format that you give, this would produce



            80 USER1
            150 USER2
            220 USER3


            The awk program simply picks out the appropriate fields from the output of du. It interprets each line as fields delimited by either spaces or slashes.



            awk -F '[ /]' ' print $1, $(NF - 1) ' would also work.



            To get this into JSON, using jq:



            du -shm /var/vmail/mailboxes/domain/*/mail |
            awk -F '[ /]' ' print $1, $7 ' |
            jq -sR 'split("n")[0:-1] | map(split(" ")) | map((.[1]):.[0]) | add'


            This would produce




            "USER1": "80",
            "USER2": "150",
            "USER3": "220"




            The jq expression first splits the input into separate array elements (one per line of input), and then splits these again on spaces into subarrays. At this point we have



            [
            [
            "80",
            "USER1"
            ],
            [
            "150",
            "USER2"
            ],
            [
            "220",
            "USER3"
            ]
            ]


            After that, objects are created with the second element in each subarray as the key and the first as the value:



            [

            "USER1": "80"
            ,

            "USER2": "150"
            ,

            "USER3": "220"

            ]


            The add at the end gives us the final result.






            share|improve this answer















            du -shm /var/vmail/mailboxes/domain/*/mail | awk -F '[ /]' ' print $1, $7 '


            With the input from du in the format that you give, this would produce



            80 USER1
            150 USER2
            220 USER3


            The awk program simply picks out the appropriate fields from the output of du. It interprets each line as fields delimited by either spaces or slashes.



            awk -F '[ /]' ' print $1, $(NF - 1) ' would also work.



            To get this into JSON, using jq:



            du -shm /var/vmail/mailboxes/domain/*/mail |
            awk -F '[ /]' ' print $1, $7 ' |
            jq -sR 'split("n")[0:-1] | map(split(" ")) | map((.[1]):.[0]) | add'


            This would produce




            "USER1": "80",
            "USER2": "150",
            "USER3": "220"




            The jq expression first splits the input into separate array elements (one per line of input), and then splits these again on spaces into subarrays. At this point we have



            [
            [
            "80",
            "USER1"
            ],
            [
            "150",
            "USER2"
            ],
            [
            "220",
            "USER3"
            ]
            ]


            After that, objects are created with the second element in each subarray as the key and the first as the value:



            [

            "USER1": "80"
            ,

            "USER2": "150"
            ,

            "USER3": "220"

            ]


            The add at the end gives us the final result.







            share|improve this answer















            share|improve this answer



            share|improve this answer








            edited May 3 at 16:02


























            answered May 3 at 15:49









            Kusalananda

            102k13199316




            102k13199316






















                up vote
                3
                down vote













                try



                du -sm /var/vmail/mailboxes/domain/*/mail |
                sed 's:/var/vmail/mailboxes/domain/::; s:/mail::'


                where




                • s:/mail:: will replace /mail by nothing

                to go to json



                du -sm /var/vmail/mailboxes/domain/*/mail |
                sed 's:/var/vmail/mailboxes/domain/::; s:/mail::' |
                awk 'BEGIN sep="" ; printf "%s "%s":%s",sep,$2,$1; sep="," END printf "n"'





                share|improve this answer























                • JSON requires keys to be double-quoted strings. Changing the printf statement to printf "%s "%s":%s",sep,$2,$1; is enough to make this generate valid JSON.
                  – Tim Kennedy
                  May 3 at 14:55














                up vote
                3
                down vote













                try



                du -sm /var/vmail/mailboxes/domain/*/mail |
                sed 's:/var/vmail/mailboxes/domain/::; s:/mail::'


                where




                • s:/mail:: will replace /mail by nothing

                to go to json



                du -sm /var/vmail/mailboxes/domain/*/mail |
                sed 's:/var/vmail/mailboxes/domain/::; s:/mail::' |
                awk 'BEGIN sep="" ; printf "%s "%s":%s",sep,$2,$1; sep="," END printf "n"'





                share|improve this answer























                • JSON requires keys to be double-quoted strings. Changing the printf statement to printf "%s "%s":%s",sep,$2,$1; is enough to make this generate valid JSON.
                  – Tim Kennedy
                  May 3 at 14:55












                up vote
                3
                down vote










                up vote
                3
                down vote









                try



                du -sm /var/vmail/mailboxes/domain/*/mail |
                sed 's:/var/vmail/mailboxes/domain/::; s:/mail::'


                where




                • s:/mail:: will replace /mail by nothing

                to go to json



                du -sm /var/vmail/mailboxes/domain/*/mail |
                sed 's:/var/vmail/mailboxes/domain/::; s:/mail::' |
                awk 'BEGIN sep="" ; printf "%s "%s":%s",sep,$2,$1; sep="," END printf "n"'





                share|improve this answer















                try



                du -sm /var/vmail/mailboxes/domain/*/mail |
                sed 's:/var/vmail/mailboxes/domain/::; s:/mail::'


                where




                • s:/mail:: will replace /mail by nothing

                to go to json



                du -sm /var/vmail/mailboxes/domain/*/mail |
                sed 's:/var/vmail/mailboxes/domain/::; s:/mail::' |
                awk 'BEGIN sep="" ; printf "%s "%s":%s",sep,$2,$1; sep="," END printf "n"'






                share|improve this answer















                share|improve this answer



                share|improve this answer








                edited May 3 at 15:58


























                answered May 3 at 14:38









                Archemar

                18.9k93365




                18.9k93365











                • JSON requires keys to be double-quoted strings. Changing the printf statement to printf "%s "%s":%s",sep,$2,$1; is enough to make this generate valid JSON.
                  – Tim Kennedy
                  May 3 at 14:55
















                • JSON requires keys to be double-quoted strings. Changing the printf statement to printf "%s "%s":%s",sep,$2,$1; is enough to make this generate valid JSON.
                  – Tim Kennedy
                  May 3 at 14:55















                JSON requires keys to be double-quoted strings. Changing the printf statement to printf "%s "%s":%s",sep,$2,$1; is enough to make this generate valid JSON.
                – Tim Kennedy
                May 3 at 14:55




                JSON requires keys to be double-quoted strings. Changing the printf statement to printf "%s "%s":%s",sep,$2,$1; is enough to make this generate valid JSON.
                – Tim Kennedy
                May 3 at 14:55










                up vote
                2
                down vote













                You can use awk to convert to 2-column format:



                $ du -shm | awk -F/ 'print $1" "$(NF - 1)'
                80 USER1
                150 USER2
                220 USER3


                For JSON, try:



                $ du -shm | awk -F/ 'print """$(NF - 1)"":"$1' | paste -sd, | printf "$(cat)" | jq

                "USER1": 80,
                "USER2": 150,
                "USER3": 220






                share|improve this answer



























                  up vote
                  2
                  down vote













                  You can use awk to convert to 2-column format:



                  $ du -shm | awk -F/ 'print $1" "$(NF - 1)'
                  80 USER1
                  150 USER2
                  220 USER3


                  For JSON, try:



                  $ du -shm | awk -F/ 'print """$(NF - 1)"":"$1' | paste -sd, | printf "$(cat)" | jq

                  "USER1": 80,
                  "USER2": 150,
                  "USER3": 220






                  share|improve this answer

























                    up vote
                    2
                    down vote










                    up vote
                    2
                    down vote









                    You can use awk to convert to 2-column format:



                    $ du -shm | awk -F/ 'print $1" "$(NF - 1)'
                    80 USER1
                    150 USER2
                    220 USER3


                    For JSON, try:



                    $ du -shm | awk -F/ 'print """$(NF - 1)"":"$1' | paste -sd, | printf "$(cat)" | jq

                    "USER1": 80,
                    "USER2": 150,
                    "USER3": 220






                    share|improve this answer















                    You can use awk to convert to 2-column format:



                    $ du -shm | awk -F/ 'print $1" "$(NF - 1)'
                    80 USER1
                    150 USER2
                    220 USER3


                    For JSON, try:



                    $ du -shm | awk -F/ 'print """$(NF - 1)"":"$1' | paste -sd, | printf "$(cat)" | jq

                    "USER1": 80,
                    "USER2": 150,
                    "USER3": 220







                    share|improve this answer















                    share|improve this answer



                    share|improve this answer








                    edited May 3 at 15:57


























                    answered May 3 at 15:50









                    kenorb

                    7,37636397




                    7,37636397




















                        up vote
                        1
                        down vote













                        jq does pretty well with raw-text, i.e. the -R flag, e.g.:



                        du -sm /var/vmail/mailboxes/domain/*/mail |
                        jq -R '
                        split(" ") |
                        .[0] as $size | # Remember size
                        .[1] | split("/") | .[-2] as $name | # Extract username
                        ($name) : ($size) # Compose object
                        '


                        Gives you:




                        "USER1": "80"


                        "USER2": "150"


                        "USER3": "220"



                        To merge the objects, use a second jq invocation:



                        ... | jq -s add


                        Output:




                        "USER1": "80",
                        "USER2": "150",
                        "USER3": "220"



                        Or in compact mode:



                        ... | jq -sc add


                        Output:



                        "USER1":"80","USER2":"150","USER3":"220"





                        share|improve this answer























                        • Why use a second invocation of jq when you could just tack add on to the end of the first jq pipeline?
                          – Kusalananda
                          May 3 at 16:05










                        • @Kusalananda: it wraps every object then
                          – Thor
                          May 3 at 16:07










                        • Ah, because they are not in an array.
                          – Kusalananda
                          May 3 at 16:20










                        • on this solution i receive the below error jq: error (at <stdin>:1): split input and separator must be strings
                          – user1521944
                          May 4 at 5:49











                        • @user1521944: are you using jq version1.5?
                          – Thor
                          May 4 at 8:56














                        up vote
                        1
                        down vote













                        jq does pretty well with raw-text, i.e. the -R flag, e.g.:



                        du -sm /var/vmail/mailboxes/domain/*/mail |
                        jq -R '
                        split(" ") |
                        .[0] as $size | # Remember size
                        .[1] | split("/") | .[-2] as $name | # Extract username
                        ($name) : ($size) # Compose object
                        '


                        Gives you:




                        "USER1": "80"


                        "USER2": "150"


                        "USER3": "220"



                        To merge the objects, use a second jq invocation:



                        ... | jq -s add


                        Output:




                        "USER1": "80",
                        "USER2": "150",
                        "USER3": "220"



                        Or in compact mode:



                        ... | jq -sc add


                        Output:



                        "USER1":"80","USER2":"150","USER3":"220"





                        share|improve this answer























                        • Why use a second invocation of jq when you could just tack add on to the end of the first jq pipeline?
                          – Kusalananda
                          May 3 at 16:05










                        • @Kusalananda: it wraps every object then
                          – Thor
                          May 3 at 16:07










                        • Ah, because they are not in an array.
                          – Kusalananda
                          May 3 at 16:20










                        • on this solution i receive the below error jq: error (at <stdin>:1): split input and separator must be strings
                          – user1521944
                          May 4 at 5:49











                        • @user1521944: are you using jq version1.5?
                          – Thor
                          May 4 at 8:56












                        up vote
                        1
                        down vote










                        up vote
                        1
                        down vote









                        jq does pretty well with raw-text, i.e. the -R flag, e.g.:



                        du -sm /var/vmail/mailboxes/domain/*/mail |
                        jq -R '
                        split(" ") |
                        .[0] as $size | # Remember size
                        .[1] | split("/") | .[-2] as $name | # Extract username
                        ($name) : ($size) # Compose object
                        '


                        Gives you:




                        "USER1": "80"


                        "USER2": "150"


                        "USER3": "220"



                        To merge the objects, use a second jq invocation:



                        ... | jq -s add


                        Output:




                        "USER1": "80",
                        "USER2": "150",
                        "USER3": "220"



                        Or in compact mode:



                        ... | jq -sc add


                        Output:



                        "USER1":"80","USER2":"150","USER3":"220"





                        share|improve this answer















                        jq does pretty well with raw-text, i.e. the -R flag, e.g.:



                        du -sm /var/vmail/mailboxes/domain/*/mail |
                        jq -R '
                        split(" ") |
                        .[0] as $size | # Remember size
                        .[1] | split("/") | .[-2] as $name | # Extract username
                        ($name) : ($size) # Compose object
                        '


                        Gives you:




                        "USER1": "80"


                        "USER2": "150"


                        "USER3": "220"



                        To merge the objects, use a second jq invocation:



                        ... | jq -s add


                        Output:




                        "USER1": "80",
                        "USER2": "150",
                        "USER3": "220"



                        Or in compact mode:



                        ... | jq -sc add


                        Output:



                        "USER1":"80","USER2":"150","USER3":"220"






                        share|improve this answer















                        share|improve this answer



                        share|improve this answer








                        edited May 3 at 16:07


























                        answered May 3 at 16:04









                        Thor

                        11k13256




                        11k13256











                        • Why use a second invocation of jq when you could just tack add on to the end of the first jq pipeline?
                          – Kusalananda
                          May 3 at 16:05










                        • @Kusalananda: it wraps every object then
                          – Thor
                          May 3 at 16:07










                        • Ah, because they are not in an array.
                          – Kusalananda
                          May 3 at 16:20










                        • on this solution i receive the below error jq: error (at <stdin>:1): split input and separator must be strings
                          – user1521944
                          May 4 at 5:49











                        • @user1521944: are you using jq version1.5?
                          – Thor
                          May 4 at 8:56
















                        • Why use a second invocation of jq when you could just tack add on to the end of the first jq pipeline?
                          – Kusalananda
                          May 3 at 16:05










                        • @Kusalananda: it wraps every object then
                          – Thor
                          May 3 at 16:07










                        • Ah, because they are not in an array.
                          – Kusalananda
                          May 3 at 16:20










                        • on this solution i receive the below error jq: error (at <stdin>:1): split input and separator must be strings
                          – user1521944
                          May 4 at 5:49











                        • @user1521944: are you using jq version1.5?
                          – Thor
                          May 4 at 8:56















                        Why use a second invocation of jq when you could just tack add on to the end of the first jq pipeline?
                        – Kusalananda
                        May 3 at 16:05




                        Why use a second invocation of jq when you could just tack add on to the end of the first jq pipeline?
                        – Kusalananda
                        May 3 at 16:05












                        @Kusalananda: it wraps every object then
                        – Thor
                        May 3 at 16:07




                        @Kusalananda: it wraps every object then
                        – Thor
                        May 3 at 16:07












                        Ah, because they are not in an array.
                        – Kusalananda
                        May 3 at 16:20




                        Ah, because they are not in an array.
                        – Kusalananda
                        May 3 at 16:20












                        on this solution i receive the below error jq: error (at <stdin>:1): split input and separator must be strings
                        – user1521944
                        May 4 at 5:49





                        on this solution i receive the below error jq: error (at <stdin>:1): split input and separator must be strings
                        – user1521944
                        May 4 at 5:49













                        @user1521944: are you using jq version1.5?
                        – Thor
                        May 4 at 8:56




                        @user1521944: are you using jq version1.5?
                        – Thor
                        May 4 at 8:56










                        up vote
                        1
                        down vote













                        This is a bit tricky to do with sed. However, here is a commented suggestion that works with GNU sed:



                        parse.sed



                        s|([^ ]+) .*/([^/]+)/.*| "2" : 1,| # Extract size and name in json-format
                        1h; 1!H # Correctly add them to hold-space
                        $
                        z # Clear pattern-space
                        s/^// # Prepend start-curly-brace
                        G # Fetch formatted json from hold-space
                        s/,$// # Remove last comma
                        s/$/n/ # Append end-curly-brace
                        p # Print



                        Run it like this:



                        du -shm /var/vmail/mailboxes/domain/*/mail | sed -Enf parse.sed


                        Or as a one-liner:



                        du -shm /var/vmail/mailboxes/domain/*/mail |
                        sed -Ene 's|([^ ]+) .*/([^/]+)/.*| "2" : 1,|;1h;1!H;$z;s/^//;G;s/,$//;s/$/n/;p'


                        Output in both cases:




                        "USER1" : 80,
                        "USER2" : 150,
                        "USER3" : 220






                        share|improve this answer



























                          up vote
                          1
                          down vote













                          This is a bit tricky to do with sed. However, here is a commented suggestion that works with GNU sed:



                          parse.sed



                          s|([^ ]+) .*/([^/]+)/.*| "2" : 1,| # Extract size and name in json-format
                          1h; 1!H # Correctly add them to hold-space
                          $
                          z # Clear pattern-space
                          s/^// # Prepend start-curly-brace
                          G # Fetch formatted json from hold-space
                          s/,$// # Remove last comma
                          s/$/n/ # Append end-curly-brace
                          p # Print



                          Run it like this:



                          du -shm /var/vmail/mailboxes/domain/*/mail | sed -Enf parse.sed


                          Or as a one-liner:



                          du -shm /var/vmail/mailboxes/domain/*/mail |
                          sed -Ene 's|([^ ]+) .*/([^/]+)/.*| "2" : 1,|;1h;1!H;$z;s/^//;G;s/,$//;s/$/n/;p'


                          Output in both cases:




                          "USER1" : 80,
                          "USER2" : 150,
                          "USER3" : 220






                          share|improve this answer

























                            up vote
                            1
                            down vote










                            up vote
                            1
                            down vote









                            This is a bit tricky to do with sed. However, here is a commented suggestion that works with GNU sed:



                            parse.sed



                            s|([^ ]+) .*/([^/]+)/.*| "2" : 1,| # Extract size and name in json-format
                            1h; 1!H # Correctly add them to hold-space
                            $
                            z # Clear pattern-space
                            s/^// # Prepend start-curly-brace
                            G # Fetch formatted json from hold-space
                            s/,$// # Remove last comma
                            s/$/n/ # Append end-curly-brace
                            p # Print



                            Run it like this:



                            du -shm /var/vmail/mailboxes/domain/*/mail | sed -Enf parse.sed


                            Or as a one-liner:



                            du -shm /var/vmail/mailboxes/domain/*/mail |
                            sed -Ene 's|([^ ]+) .*/([^/]+)/.*| "2" : 1,|;1h;1!H;$z;s/^//;G;s/,$//;s/$/n/;p'


                            Output in both cases:




                            "USER1" : 80,
                            "USER2" : 150,
                            "USER3" : 220






                            share|improve this answer















                            This is a bit tricky to do with sed. However, here is a commented suggestion that works with GNU sed:



                            parse.sed



                            s|([^ ]+) .*/([^/]+)/.*| "2" : 1,| # Extract size and name in json-format
                            1h; 1!H # Correctly add them to hold-space
                            $
                            z # Clear pattern-space
                            s/^// # Prepend start-curly-brace
                            G # Fetch formatted json from hold-space
                            s/,$// # Remove last comma
                            s/$/n/ # Append end-curly-brace
                            p # Print



                            Run it like this:



                            du -shm /var/vmail/mailboxes/domain/*/mail | sed -Enf parse.sed


                            Or as a one-liner:



                            du -shm /var/vmail/mailboxes/domain/*/mail |
                            sed -Ene 's|([^ ]+) .*/([^/]+)/.*| "2" : 1,|;1h;1!H;$z;s/^//;G;s/,$//;s/$/n/;p'


                            Output in both cases:




                            "USER1" : 80,
                            "USER2" : 150,
                            "USER3" : 220







                            share|improve this answer















                            share|improve this answer



                            share|improve this answer








                            edited May 3 at 16:33


























                            answered May 3 at 16:24









                            Thor

                            11k13256




                            11k13256






















                                 

                                draft saved


                                draft discarded


























                                 


                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f441568%2fparse-du-result-using-sed%23new-answer', 'question_page');

                                );

                                Post as a guest













































































                                Popular posts from this blog

                                How to check contact read email or not when send email to Individual?

                                Displaying single band from multi-band raster using QGIS

                                How many registers does an x86_64 CPU actually have?