Quizás no tenga suerte, porque mi archivo CSV separado por comas tiene comillas dobles y comas dentro del texto útil.
Entonces quiero convertir esto:
"record 1","name 1","text 1, text 2"
"record 2","name ""2""","text 2"
"record 3","name 3",""
en ese:
"record 1","name 1","text 1, text 2"
"record 2","name 2","text 2"
"record 3","name 3",""
Observe que eliminé las comillas dobles de name ""2""
to name 2
, pero conservé las comillas dobles de la línea n.° 3:,""
Respuesta1
Usar csvformat
para convertir los delimitadores en tabulaciones ( csvformat -T
), eliminar las comillas dobles ( tr -d '"'
) y luego devolver los delimitadores a comas mientras se citan todos los campos (el último fragmento de la canalización):
$ csvformat -T file.csv | tr -d '"' | csvformat -t -U1
"record 1","name 1","text 1, text 2"
"record 2","name 2","text 2"
"record 3","name 3",""
csvformat
es parte decsvkit
.
Respuesta2
Esto funcionará sin importar qué caracteres haya en su entrada (excepto las nuevas líneas dentro de los campos entre comillas, pero ese es un problema completamente diferente).
Con GNU awk para FPAT:
$ awk -v FPAT='("[^"]*")+' -v OFS='","' '{
for ( i=1; i<=NF; i++ ) {
gsub(/"/,"",$i)
}
print "\"" $0 "\""
}' file
"record 1","name 1","text 1, text 2"
"record 2","name 2","text 2"
"record 3","name 3",""
o el equivalente con cualquier awk:
$ awk -v OFS='","' '{
orig=$0; $0=""; i=0;
while ( match(orig,/("[^"]*")+/) ) {
$(++i) = substr(orig,RSTART,RLENGTH)
gsub(/"/,"",$i)
orig = substr(orig,RSTART+RLENGTH)
}
print "\"" $0 "\""
}' file
"record 1","name 1","text 1, text 2"
"record 2","name 2","text 2"
"record 3","name 3",""
Ver también¿cuál-es-la-forma-más-sólida-de-analizar-csv-eficientemente-usando-awk?.