torr / awk para remover aspas duplas "que estão dentro das chaves {}

5

Eu tenho um arquivo csv com dados semelhantes a este:

"1b579a5e-9701-40eb-bd36-2bc65169da99","week14_Friday-019","6907eaad-1aff-4d26-9088-ba20374b67c0","2181-019","f20af5bb-c716-42e0-9b9d-cbolf5bfecea","15-BIO-2001","COLLEGE Bio 1","d39330be-df56-4365-8fb4-37e68d040c52","Which engine has the smaller efficiency?","{choices:[a","b","c","d],"type:MultipleChoice}","{solution:[0],"selectAll:false,{"selectMultiple:false",}"type:MultipleChoice}","2016-04-25 00:30:19.000","1922ac5a-6ff6-4ea4-9078-6df4d85d294f","{solution:[0],"type:MultipleChoice}","1","1116911f-8ee5-45c3-b173-a6be681bb15a","FakeLastName","FakeFirstName","[email protected]","Student"

Eu quero remover as aspas duplas ", mas somente se elas estiverem dentro das chaves {}, de preferência com sed ou awk. A saída desejada é:

"1b579a5e-9701-40eb-bd36-2bc65169da99","week14_Friday-019","6907eaad-1aff-4d26-9088-ba20374b67c0","2181-019","f20af5bb-c716-42e0-9b9d-cbolf5bfecea","15-BIO-2001","COLLEGE Bio 1","d39330be-df56-4365-8fb4-37e68d040c52","Which engine has the smaller efficiency?","{choices:[a,b,c,d],type:MultipleChoice}","{solution:[0],selectAll:false,{selectMultiple:false,}type:MultipleChoice}","2016-04-25 00:30:19.000","1922ac5a-6ff6-4ea4-9078-6df4d85d294f","{solution:[0],type:MultipleChoice}","1","1116911f-8ee5-45c3-b173-a6be681bb15a","FakeLastName","FakeFirstName","[email protected]","Student"

Qualquer ajuda seria muito apreciada. Obrigado!

    
por Brock Winfrey 07.08.2018 / 15:55

3 respostas

8

Seria mais fácil com sed :

sed -e :1 -e 's/\({[^}]*\)"\([^}]*}\)//g; t1'

Ou perl :

perl -pe 's{\{.*?\}}{$& =~ s/"//gr}ge'

Observe que não há aninhados {...} .

Para lidar com {...} aninhado, você pode usar os recursos de expressão regular recursiva de perl :

perl -pe 's(\{(?:[^{}]++|(?0))*\})($& =~ s/"//gr)ge'

Com sed , trabalhando para fora para escapar do interior {...} s antes de remover o " s:

sed 's/_/_u/g
     :1
     s/\({[^{}]*\){\([^{}]*\)}/_<_>/g; t1
     :2
     s/\({[^}]*\)"\([^}]*}\)//g; t2
     s/_</{/g; s/_>/}/g;s/_u/_/g'
    
por 07.08.2018 / 17:12
1

Tente isso usando sed :

$ sed -r ' :L; s/(\{[^"}]*)"(([^"}]*")*)([^"}]*\})//g; tL; ' file
    
por 07.08.2018 / 17:05
0

awk para chaves aninhadas:

    awk -F{ '
            {for (i=2; i<=NF; i++)  {if (1 == n = split ($i, T, "}")) n++ 
                                     for (j=1; j<n; j++)    {RS = index ($i, T[j])
                                                             L = gsub (/"/, _, T[j])
                                                             $i = substr ($i, 1, RS-1)  T[j]   substr ($i, RS + length (T[j]) + L)
                                                            }
                                    }
            }
    1' OFS="{" file

Desajeitado, mas produz a saída especificada, pelo menos para chaves aninhadas individualmente.

    
por 07.08.2018 / 20:22

Tags