separate fields by comma using bash

前端 未结 8 1415
滥情空心
滥情空心 2021-01-25 01:07

How do I place commas between fields?

Input data

12123 \'QA test case 1\' \'QA environment\'   
12234 \'UAT test case 1\' \'UAT environment\'  


        
相关标签:
8条回答
  • 2021-01-25 02:01

    Here is how I handle csv with awk

    cat file
    12123 'QA test case 1' 'QA environment' some more
    12234 'UAT test case 1' 'UAT environment'
    

    awk '{for (i=1;i<NF;i++) {if ($i~t) c++;printf "%s"(c%2?FS:", "),$i}print $NF}' t=\' file
    12123, 'QA test case 1', 'QA environment', some, more
    12234, 'UAT test case 1', 'UAT environment'
    

    This keep track of how many ' it finds.
    If its 0 2 4 6 etc you are outside a group, split using ,
    If its 1 3 5 7 etc you are inside a group, split by (a space)


    Since you now have a good separator, you can get rid of the '

    awk '{for (i=1;i<NF;i++) {if ($i~t) c++;sub(t,"",$i);printf "%s"(c%2?FS:","),$i}sub(t,"",$NF);print $NF}' t=\' file
    12123,QA test case 1,QA environment,some,more
    12234,UAT test case 1,UAT environment
    

    You could also use FPAT that is used to define fields, opposed to FS that define separators, but then you need gnu awk 4.x, and it would not be portable.

    awk '{for (i=1;i<NF;i++) printf "%s, ",$i;print $NF}' FPAT="[^' ]+|'[^']+'" file
    12123, 'QA test case 1', 'QA environment', some, more
    12234, 'UAT test case 1', 'UAT environment'
    

    How does the FPAT="[^' ]+|'[^']+'" works?
    1. A field should not contain one or more ' or space. [^' ]+ eks some and more
    2. A field starts with ' then one or more not ' and then ends with '. '[^']+' eks 'test data'

    0 讨论(0)
  • 2021-01-25 02:06

    This solution (I believe) is not very nice, but standard at least:

    awk 'BEGIN{SP="[:space:]"}{gsub("(["SP"]*('\''[^'\'']*'\''|[^'\''"SP"])+)","&,");if(match($0, (",["SP"]+$")))$0=substr($0,1,RSTART-1)substr($0,RSTART+1)}1'
    

    Though some "broken" awk implementations don't support character classes with the [[:foo:]] style, in that case you can use:

    awk 'BEGIN{SP=" \t\f\v\r\n"}{gsub("(["SP"]*('\''[^'\'']*'\''|[^'\''"SP"])+)","&,");if(match($0, (",["SP"]+$")))$0=substr($0,1,RSTART-1)substr($0,RSTART+1)}1'
    

    Note: I used '\'' to place each single quote character because that's a simple and standard way to do it. If you want to use this line in a ".awk" file, just replace every occurrence with a single quote.

    0 讨论(0)
提交回复
热议问题