trim tailing - and add it leading for Numbers in shell

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











up vote
1
down vote

favorite












I have a CSV file with numbers in double quotes and without double quotes and for some numbers. I have to fix the negative symbols for only numbers: the tailing negative symbol has to be removed and added to the beginning.



Sample Input:



column 1, column 2, column 3, column 4, column 5
12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787


Sample Output:



column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787






share|improve this question






















  • When you say string with quotes, is that double quotes? How are they encoded? By doubling the " like in most CSV formats? Or with " as sometimes seen? Can the strings contain newline characters? It would be better to have a real example there.
    – Stéphane Chazelas
    Dec 6 '17 at 10:40















up vote
1
down vote

favorite












I have a CSV file with numbers in double quotes and without double quotes and for some numbers. I have to fix the negative symbols for only numbers: the tailing negative symbol has to be removed and added to the beginning.



Sample Input:



column 1, column 2, column 3, column 4, column 5
12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787


Sample Output:



column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787






share|improve this question






















  • When you say string with quotes, is that double quotes? How are they encoded? By doubling the " like in most CSV formats? Or with " as sometimes seen? Can the strings contain newline characters? It would be better to have a real example there.
    – Stéphane Chazelas
    Dec 6 '17 at 10:40













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have a CSV file with numbers in double quotes and without double quotes and for some numbers. I have to fix the negative symbols for only numbers: the tailing negative symbol has to be removed and added to the beginning.



Sample Input:



column 1, column 2, column 3, column 4, column 5
12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787


Sample Output:



column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787






share|improve this question














I have a CSV file with numbers in double quotes and without double quotes and for some numbers. I have to fix the negative symbols for only numbers: the tailing negative symbol has to be removed and added to the beginning.



Sample Input:



column 1, column 2, column 3, column 4, column 5
12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787


Sample Output:



column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787








share|improve this question













share|improve this question




share|improve this question








edited Dec 6 '17 at 9:38









fpmurphy1

2,231915




2,231915










asked Dec 5 '17 at 20:33









Kiran

142




142











  • When you say string with quotes, is that double quotes? How are they encoded? By doubling the " like in most CSV formats? Or with " as sometimes seen? Can the strings contain newline characters? It would be better to have a real example there.
    – Stéphane Chazelas
    Dec 6 '17 at 10:40

















  • When you say string with quotes, is that double quotes? How are they encoded? By doubling the " like in most CSV formats? Or with " as sometimes seen? Can the strings contain newline characters? It would be better to have a real example there.
    – Stéphane Chazelas
    Dec 6 '17 at 10:40
















When you say string with quotes, is that double quotes? How are they encoded? By doubling the " like in most CSV formats? Or with " as sometimes seen? Can the strings contain newline characters? It would be better to have a real example there.
– Stéphane Chazelas
Dec 6 '17 at 10:40





When you say string with quotes, is that double quotes? How are they encoded? By doubling the " like in most CSV formats? Or with " as sometimes seen? Can the strings contain newline characters? It would be better to have a real example there.
– Stéphane Chazelas
Dec 6 '17 at 10:40











5 Answers
5






active

oldest

votes

















up vote
1
down vote













GNU awk solution:



awk -v FPAT='[^,"]+|"[^"]+"' '
NR==1; NR>1
for (i=1; i<=NF; i++)
if ($i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/)
sub(/-/, "", $i);
sub(/[0-9]/, "-&", $i);

printf "%s%s",$i,(i==NF? ORS:",")

' file.csv



  • -v FPAT='[^,"]+|"[^"]+"' - regex pattern defining field value


  • $i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/ - check if a field contains a number with trailing minus sign - (number could be double-quoted)


The output:



column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787





share|improve this answer




















  • I see it's not working for the same data set I used. Still the negative remains at tailing.
    – Kiran
    Dec 5 '17 at 22:55











  • @Kiran, that's not true ... and here's the screenshot ibb.co/jbzZ9b
    – RomanPerekhrest
    Dec 5 '17 at 23:02










  • @Kiran FPAT requires gawk version 4. What is the output of gawk --version?
    – fpmurphy1
    Dec 6 '17 at 0:24


















up vote
0
down vote













CSV data requires a CSV parser. Ruby has one:



$ cat file.csv
12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787

$ ruby -rcsv -e '
CSV.foreach(ARGV.shift) do |row|
corrected = row.collect
puts CSV.generate_line(corrected)
end
' file.csv




-12,"-455,365.44",string with quotes-and with a comma in between,"4,432",6787


The CSV generator decided that the "string with quotes" did not need to be quoted because it does not contain a comma.






share|improve this answer




















  • I downvoted this answer because of the quote stripping.
    – fpmurphy1
    Dec 6 '17 at 4:07

















up vote
0
down vote













awk solution that does not use gawk FPAT:



NR==1;

NR > 1
$0 = $0","

while ($0)
( f ~ /^[0-9]+[.]?[0-9]+-$/ )



Output for supplied sample file is:



column 1, column 2, column 3, column 4, column 5
-12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787





share|improve this answer



























    up vote
    0
    down vote













    With perl, but not suitable for all sorts of csv formats, works for given sample



    $ perl -ne '@cols=/"[^"]+"|[^,]+/g;
    map s/"(.*)-"$/"-$1"/ or s/(.*)-$/-$1/ @cols;
    print join ",", @cols' ip.csv
    column 1, column 2, column 3, column 4, column 5
    -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787



    • @cols=/"[^"]+"|[^,]+/g save fields in array


    • map s/"(.*)-"$/"-$1"/ or s/(.*)-$/-$1/ @cols change each element of array. The second substitution is used only if first doesn't succeed

      • change (.*) to ([d,.]+) to sort of restrict the matching to digits and , and . only. This would still match strings like ..,..-



    • print join ",", @cols print the changed array with , as separator



    a bit of fun without using temp array



    perl -ne 'print join ",", map /^"/ ? s/"(.*)-"$/"-$1"/r : s/(.*)-$/-$1/r /"[^"]+"|[^,]+/g'





    share|improve this answer





























      up vote
      0
      down vote













      With sed implementations supporting -E, assuming the double quotes embedded in string fields are encoded as "" and that those string fields don't contain newline characters:



      sed -E '
      :1
      s/^(("[^"]*"|[^"])*,)?([0-9.]+)-(,|$)/1-34/;
      s/^(("[^"]*"|[^"])*,)?"([0-9,.]+)-"(,|$)/1"-3"4/
      t1' < file


      Depending on the nature of the input, you may want to be stricter in matching the numbers. For instance ([0-9.]+)- here would match on 12- but also on ...-. If that type of input may occur in the input, you could change it to ([0-9]*.?[0-9]+)- for instance.






      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%2f409026%2ftrim-tailing-and-add-it-leading-for-numbers-in-shell%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
        1
        down vote













        GNU awk solution:



        awk -v FPAT='[^,"]+|"[^"]+"' '
        NR==1; NR>1
        for (i=1; i<=NF; i++)
        if ($i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/)
        sub(/-/, "", $i);
        sub(/[0-9]/, "-&", $i);

        printf "%s%s",$i,(i==NF? ORS:",")

        ' file.csv



        • -v FPAT='[^,"]+|"[^"]+"' - regex pattern defining field value


        • $i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/ - check if a field contains a number with trailing minus sign - (number could be double-quoted)


        The output:



        column 1, column 2, column 3, column 4, column 5
        -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787





        share|improve this answer




















        • I see it's not working for the same data set I used. Still the negative remains at tailing.
          – Kiran
          Dec 5 '17 at 22:55











        • @Kiran, that's not true ... and here's the screenshot ibb.co/jbzZ9b
          – RomanPerekhrest
          Dec 5 '17 at 23:02










        • @Kiran FPAT requires gawk version 4. What is the output of gawk --version?
          – fpmurphy1
          Dec 6 '17 at 0:24















        up vote
        1
        down vote













        GNU awk solution:



        awk -v FPAT='[^,"]+|"[^"]+"' '
        NR==1; NR>1
        for (i=1; i<=NF; i++)
        if ($i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/)
        sub(/-/, "", $i);
        sub(/[0-9]/, "-&", $i);

        printf "%s%s",$i,(i==NF? ORS:",")

        ' file.csv



        • -v FPAT='[^,"]+|"[^"]+"' - regex pattern defining field value


        • $i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/ - check if a field contains a number with trailing minus sign - (number could be double-quoted)


        The output:



        column 1, column 2, column 3, column 4, column 5
        -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787





        share|improve this answer




















        • I see it's not working for the same data set I used. Still the negative remains at tailing.
          – Kiran
          Dec 5 '17 at 22:55











        • @Kiran, that's not true ... and here's the screenshot ibb.co/jbzZ9b
          – RomanPerekhrest
          Dec 5 '17 at 23:02










        • @Kiran FPAT requires gawk version 4. What is the output of gawk --version?
          – fpmurphy1
          Dec 6 '17 at 0:24













        up vote
        1
        down vote










        up vote
        1
        down vote









        GNU awk solution:



        awk -v FPAT='[^,"]+|"[^"]+"' '
        NR==1; NR>1
        for (i=1; i<=NF; i++)
        if ($i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/)
        sub(/-/, "", $i);
        sub(/[0-9]/, "-&", $i);

        printf "%s%s",$i,(i==NF? ORS:",")

        ' file.csv



        • -v FPAT='[^,"]+|"[^"]+"' - regex pattern defining field value


        • $i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/ - check if a field contains a number with trailing minus sign - (number could be double-quoted)


        The output:



        column 1, column 2, column 3, column 4, column 5
        -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787





        share|improve this answer












        GNU awk solution:



        awk -v FPAT='[^,"]+|"[^"]+"' '
        NR==1; NR>1
        for (i=1; i<=NF; i++)
        if ($i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/)
        sub(/-/, "", $i);
        sub(/[0-9]/, "-&", $i);

        printf "%s%s",$i,(i==NF? ORS:",")

        ' file.csv



        • -v FPAT='[^,"]+|"[^"]+"' - regex pattern defining field value


        • $i~/^"?[0-9]+([0-9,.]+[0-9]+)?-"?$/ - check if a field contains a number with trailing minus sign - (number could be double-quoted)


        The output:



        column 1, column 2, column 3, column 4, column 5
        -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 5 '17 at 22:24









        RomanPerekhrest

        22.4k12145




        22.4k12145











        • I see it's not working for the same data set I used. Still the negative remains at tailing.
          – Kiran
          Dec 5 '17 at 22:55











        • @Kiran, that's not true ... and here's the screenshot ibb.co/jbzZ9b
          – RomanPerekhrest
          Dec 5 '17 at 23:02










        • @Kiran FPAT requires gawk version 4. What is the output of gawk --version?
          – fpmurphy1
          Dec 6 '17 at 0:24

















        • I see it's not working for the same data set I used. Still the negative remains at tailing.
          – Kiran
          Dec 5 '17 at 22:55











        • @Kiran, that's not true ... and here's the screenshot ibb.co/jbzZ9b
          – RomanPerekhrest
          Dec 5 '17 at 23:02










        • @Kiran FPAT requires gawk version 4. What is the output of gawk --version?
          – fpmurphy1
          Dec 6 '17 at 0:24
















        I see it's not working for the same data set I used. Still the negative remains at tailing.
        – Kiran
        Dec 5 '17 at 22:55





        I see it's not working for the same data set I used. Still the negative remains at tailing.
        – Kiran
        Dec 5 '17 at 22:55













        @Kiran, that's not true ... and here's the screenshot ibb.co/jbzZ9b
        – RomanPerekhrest
        Dec 5 '17 at 23:02




        @Kiran, that's not true ... and here's the screenshot ibb.co/jbzZ9b
        – RomanPerekhrest
        Dec 5 '17 at 23:02












        @Kiran FPAT requires gawk version 4. What is the output of gawk --version?
        – fpmurphy1
        Dec 6 '17 at 0:24





        @Kiran FPAT requires gawk version 4. What is the output of gawk --version?
        – fpmurphy1
        Dec 6 '17 at 0:24













        up vote
        0
        down vote













        CSV data requires a CSV parser. Ruby has one:



        $ cat file.csv
        12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787

        $ ruby -rcsv -e '
        CSV.foreach(ARGV.shift) do |row|
        corrected = row.collect
        puts CSV.generate_line(corrected)
        end
        ' file.csv




        -12,"-455,365.44",string with quotes-and with a comma in between,"4,432",6787


        The CSV generator decided that the "string with quotes" did not need to be quoted because it does not contain a comma.






        share|improve this answer




















        • I downvoted this answer because of the quote stripping.
          – fpmurphy1
          Dec 6 '17 at 4:07














        up vote
        0
        down vote













        CSV data requires a CSV parser. Ruby has one:



        $ cat file.csv
        12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787

        $ ruby -rcsv -e '
        CSV.foreach(ARGV.shift) do |row|
        corrected = row.collect
        puts CSV.generate_line(corrected)
        end
        ' file.csv




        -12,"-455,365.44",string with quotes-and with a comma in between,"4,432",6787


        The CSV generator decided that the "string with quotes" did not need to be quoted because it does not contain a comma.






        share|improve this answer




















        • I downvoted this answer because of the quote stripping.
          – fpmurphy1
          Dec 6 '17 at 4:07












        up vote
        0
        down vote










        up vote
        0
        down vote









        CSV data requires a CSV parser. Ruby has one:



        $ cat file.csv
        12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787

        $ ruby -rcsv -e '
        CSV.foreach(ARGV.shift) do |row|
        corrected = row.collect
        puts CSV.generate_line(corrected)
        end
        ' file.csv




        -12,"-455,365.44",string with quotes-and with a comma in between,"4,432",6787


        The CSV generator decided that the "string with quotes" did not need to be quoted because it does not contain a comma.






        share|improve this answer












        CSV data requires a CSV parser. Ruby has one:



        $ cat file.csv
        12-,"455,365.44-","string with quotes-and with a comma in between","4,432",6787

        $ ruby -rcsv -e '
        CSV.foreach(ARGV.shift) do |row|
        corrected = row.collect
        puts CSV.generate_line(corrected)
        end
        ' file.csv




        -12,"-455,365.44",string with quotes-and with a comma in between,"4,432",6787


        The CSV generator decided that the "string with quotes" did not need to be quoted because it does not contain a comma.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Dec 5 '17 at 22:07









        glenn jackman

        46.8k265103




        46.8k265103











        • I downvoted this answer because of the quote stripping.
          – fpmurphy1
          Dec 6 '17 at 4:07
















        • I downvoted this answer because of the quote stripping.
          – fpmurphy1
          Dec 6 '17 at 4:07















        I downvoted this answer because of the quote stripping.
        – fpmurphy1
        Dec 6 '17 at 4:07




        I downvoted this answer because of the quote stripping.
        – fpmurphy1
        Dec 6 '17 at 4:07










        up vote
        0
        down vote













        awk solution that does not use gawk FPAT:



        NR==1;

        NR > 1
        $0 = $0","

        while ($0)
        ( f ~ /^[0-9]+[.]?[0-9]+-$/ )



        Output for supplied sample file is:



        column 1, column 2, column 3, column 4, column 5
        -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787





        share|improve this answer
























          up vote
          0
          down vote













          awk solution that does not use gawk FPAT:



          NR==1;

          NR > 1
          $0 = $0","

          while ($0)
          ( f ~ /^[0-9]+[.]?[0-9]+-$/ )



          Output for supplied sample file is:



          column 1, column 2, column 3, column 4, column 5
          -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787





          share|improve this answer






















            up vote
            0
            down vote










            up vote
            0
            down vote









            awk solution that does not use gawk FPAT:



            NR==1;

            NR > 1
            $0 = $0","

            while ($0)
            ( f ~ /^[0-9]+[.]?[0-9]+-$/ )



            Output for supplied sample file is:



            column 1, column 2, column 3, column 4, column 5
            -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787





            share|improve this answer












            awk solution that does not use gawk FPAT:



            NR==1;

            NR > 1
            $0 = $0","

            while ($0)
            ( f ~ /^[0-9]+[.]?[0-9]+-$/ )



            Output for supplied sample file is:



            column 1, column 2, column 3, column 4, column 5
            -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Dec 6 '17 at 2:41









            fpmurphy1

            2,231915




            2,231915




















                up vote
                0
                down vote













                With perl, but not suitable for all sorts of csv formats, works for given sample



                $ perl -ne '@cols=/"[^"]+"|[^,]+/g;
                map s/"(.*)-"$/"-$1"/ or s/(.*)-$/-$1/ @cols;
                print join ",", @cols' ip.csv
                column 1, column 2, column 3, column 4, column 5
                -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787



                • @cols=/"[^"]+"|[^,]+/g save fields in array


                • map s/"(.*)-"$/"-$1"/ or s/(.*)-$/-$1/ @cols change each element of array. The second substitution is used only if first doesn't succeed

                  • change (.*) to ([d,.]+) to sort of restrict the matching to digits and , and . only. This would still match strings like ..,..-



                • print join ",", @cols print the changed array with , as separator



                a bit of fun without using temp array



                perl -ne 'print join ",", map /^"/ ? s/"(.*)-"$/"-$1"/r : s/(.*)-$/-$1/r /"[^"]+"|[^,]+/g'





                share|improve this answer


























                  up vote
                  0
                  down vote













                  With perl, but not suitable for all sorts of csv formats, works for given sample



                  $ perl -ne '@cols=/"[^"]+"|[^,]+/g;
                  map s/"(.*)-"$/"-$1"/ or s/(.*)-$/-$1/ @cols;
                  print join ",", @cols' ip.csv
                  column 1, column 2, column 3, column 4, column 5
                  -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787



                  • @cols=/"[^"]+"|[^,]+/g save fields in array


                  • map s/"(.*)-"$/"-$1"/ or s/(.*)-$/-$1/ @cols change each element of array. The second substitution is used only if first doesn't succeed

                    • change (.*) to ([d,.]+) to sort of restrict the matching to digits and , and . only. This would still match strings like ..,..-



                  • print join ",", @cols print the changed array with , as separator



                  a bit of fun without using temp array



                  perl -ne 'print join ",", map /^"/ ? s/"(.*)-"$/"-$1"/r : s/(.*)-$/-$1/r /"[^"]+"|[^,]+/g'





                  share|improve this answer
























                    up vote
                    0
                    down vote










                    up vote
                    0
                    down vote









                    With perl, but not suitable for all sorts of csv formats, works for given sample



                    $ perl -ne '@cols=/"[^"]+"|[^,]+/g;
                    map s/"(.*)-"$/"-$1"/ or s/(.*)-$/-$1/ @cols;
                    print join ",", @cols' ip.csv
                    column 1, column 2, column 3, column 4, column 5
                    -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787



                    • @cols=/"[^"]+"|[^,]+/g save fields in array


                    • map s/"(.*)-"$/"-$1"/ or s/(.*)-$/-$1/ @cols change each element of array. The second substitution is used only if first doesn't succeed

                      • change (.*) to ([d,.]+) to sort of restrict the matching to digits and , and . only. This would still match strings like ..,..-



                    • print join ",", @cols print the changed array with , as separator



                    a bit of fun without using temp array



                    perl -ne 'print join ",", map /^"/ ? s/"(.*)-"$/"-$1"/r : s/(.*)-$/-$1/r /"[^"]+"|[^,]+/g'





                    share|improve this answer














                    With perl, but not suitable for all sorts of csv formats, works for given sample



                    $ perl -ne '@cols=/"[^"]+"|[^,]+/g;
                    map s/"(.*)-"$/"-$1"/ or s/(.*)-$/-$1/ @cols;
                    print join ",", @cols' ip.csv
                    column 1, column 2, column 3, column 4, column 5
                    -12,"-455,365.44","string with quotes-and with a comma in between","4,432",6787



                    • @cols=/"[^"]+"|[^,]+/g save fields in array


                    • map s/"(.*)-"$/"-$1"/ or s/(.*)-$/-$1/ @cols change each element of array. The second substitution is used only if first doesn't succeed

                      • change (.*) to ([d,.]+) to sort of restrict the matching to digits and , and . only. This would still match strings like ..,..-



                    • print join ",", @cols print the changed array with , as separator



                    a bit of fun without using temp array



                    perl -ne 'print join ",", map /^"/ ? s/"(.*)-"$/"-$1"/r : s/(.*)-$/-$1/r /"[^"]+"|[^,]+/g'






                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Dec 6 '17 at 6:12

























                    answered Dec 6 '17 at 6:01









                    Sundeep

                    6,9511826




                    6,9511826




















                        up vote
                        0
                        down vote













                        With sed implementations supporting -E, assuming the double quotes embedded in string fields are encoded as "" and that those string fields don't contain newline characters:



                        sed -E '
                        :1
                        s/^(("[^"]*"|[^"])*,)?([0-9.]+)-(,|$)/1-34/;
                        s/^(("[^"]*"|[^"])*,)?"([0-9,.]+)-"(,|$)/1"-3"4/
                        t1' < file


                        Depending on the nature of the input, you may want to be stricter in matching the numbers. For instance ([0-9.]+)- here would match on 12- but also on ...-. If that type of input may occur in the input, you could change it to ([0-9]*.?[0-9]+)- for instance.






                        share|improve this answer
























                          up vote
                          0
                          down vote













                          With sed implementations supporting -E, assuming the double quotes embedded in string fields are encoded as "" and that those string fields don't contain newline characters:



                          sed -E '
                          :1
                          s/^(("[^"]*"|[^"])*,)?([0-9.]+)-(,|$)/1-34/;
                          s/^(("[^"]*"|[^"])*,)?"([0-9,.]+)-"(,|$)/1"-3"4/
                          t1' < file


                          Depending on the nature of the input, you may want to be stricter in matching the numbers. For instance ([0-9.]+)- here would match on 12- but also on ...-. If that type of input may occur in the input, you could change it to ([0-9]*.?[0-9]+)- for instance.






                          share|improve this answer






















                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            With sed implementations supporting -E, assuming the double quotes embedded in string fields are encoded as "" and that those string fields don't contain newline characters:



                            sed -E '
                            :1
                            s/^(("[^"]*"|[^"])*,)?([0-9.]+)-(,|$)/1-34/;
                            s/^(("[^"]*"|[^"])*,)?"([0-9,.]+)-"(,|$)/1"-3"4/
                            t1' < file


                            Depending on the nature of the input, you may want to be stricter in matching the numbers. For instance ([0-9.]+)- here would match on 12- but also on ...-. If that type of input may occur in the input, you could change it to ([0-9]*.?[0-9]+)- for instance.






                            share|improve this answer












                            With sed implementations supporting -E, assuming the double quotes embedded in string fields are encoded as "" and that those string fields don't contain newline characters:



                            sed -E '
                            :1
                            s/^(("[^"]*"|[^"])*,)?([0-9.]+)-(,|$)/1-34/;
                            s/^(("[^"]*"|[^"])*,)?"([0-9,.]+)-"(,|$)/1"-3"4/
                            t1' < file


                            Depending on the nature of the input, you may want to be stricter in matching the numbers. For instance ([0-9.]+)- here would match on 12- but also on ...-. If that type of input may occur in the input, you could change it to ([0-9]*.?[0-9]+)- for instance.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Dec 6 '17 at 10:49









                            Stéphane Chazelas

                            282k53520854




                            282k53520854



























                                 

                                draft saved


                                draft discarded















































                                 


                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f409026%2ftrim-tailing-and-add-it-leading-for-numbers-in-shell%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?