Encontre e adicione aspas entre uma string específica

Encontre e adicione aspas entre uma string específica

quando estou trabalhando com csv, vírgulas indesejadas (',') enganam meu arquivo csv e, como resultado, causam inconsistência.

por favor encontre em detalhes abaixo.

Meu arquivo csv de amostra:

1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4

Quero o resultado final como:

1|"a,b"|4
1|"c,d"|4
1|"e,f"|4
1|"g,h"|4
1|"i,j"|4

Depois de adicionar as aspas, substituirei "|" com "," para que meu csv funcione como eu esperava.

Usei o comando abaixo, mas não está dando conforme o esperado.

sed -e 's/,/"&"/' file1.txt

Responder1

Usando csvformatdecsvkit, e assumindo que o resultado final deve ser um arquivo CSV com vírgula como delimitador (conforme descrito no texto da pergunta):

$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4

Isso reformata o arquivo CSV de ter |caracteres como delimitador para ter a vírgula padrão como delimitador. Ao fazer isso, ele cita corretamente os campos que precisam ser citados.

Isso também lida adequadamente com campos com novas linhas incorporadas:

$ cat file
1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4
2|"line 1,
line2"|5
$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
2,"line 1,
line2",5

Se você tiver um documento em algum formato estruturado, como CSV, JSON, XML, YAML, TOML, etc., não há razãonãopara usar um analisador para esse formato de documento para analisar esse documento.

Responder2

Você poderia fazer:

awk -F'[|]' -v OFS=',' -v q='"' '{ for(i=1; i<=NF; i++) $i=q $i q }1' infile

com -F'[|]'definimos o separador de campo de entrada.
com -v OFS=','definimos o separador de campo de saída.
NFidentifica quantos campos existem em cada linha/registro com base no FS (separador de campos de entrada), então fazemos um loop sobre o número de campos e adicionamos aspas duplas para cada um deles e imprimimos a atualização final na linha com1idioma do awkpara a impressão.

observe que todos os campos estão sendo citados com este comando, o que obviamente não é um problema por ter um arquivo CSV válido.

Responder3

Com sed:

$ sed 's/[^|]*,[^|]*/"&"/g; y/|/,/' ip.txt
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
  • s/[^|]*,[^|]*/"&"/gadicione aspas duplas a todos os campos que contêm,
  • y/|/,/mude todos os |caracteres para,

Com perl:

perl -F'\|' -lane 'print join ",", map {/,/ ? qq("$_") : $_} @F'

Isso é usado |como separador de campo de entrada. Em seguida, mapadicionaremos aspas duplas para todos os campos que contenham ,. Finalmente, joiné usado para combinar os campos com ,caracteres.

Responder4

Outra sedmaneira:

  sed 's;\([^|]*\)|\([^|]*\)|\(.*\)$;\1,"\2",\3;' data

Ou se você sedsuporta o carregamento de ERE, como GNU sed, você pode evitar todo o trabalho de escape:

  sed -E 's;([^|]+)\|([^|]+)\|(.+)$;\1,"\2",\3;' data

Você pode explorar o fato de que apenas o grupo do meio é delimitado por um |em cada limite e torná-lo sedainda mais curto:

sed 's;|\([^|]*\)|;,"\1",;' data

Claro que também aqui, se o seu suporte sed -Evocê pode carregar EREe evitar um tedioso trabalho de fuga

informação relacionada