Cuando trabajo con csv, las comas no deseadas (',') confunden mi archivo csv y, como resultado, generan inconsistencia.
por favor encuentre los detalles a continuación.
Mi archivo csv de muestra:
1|a,b|4
1|c,d|4
1|e,f|4
1|g,h|4
1|i,j|4
Quiero el resultado final como:
1|"a,b"|4
1|"c,d"|4
1|"e,f"|4
1|"g,h"|4
1|"i,j"|4
Después de agregar las comillas, reemplazaré "|" con "," para que mi csv funcione como esperaba.
Utilicé el siguiente comando pero no funciona como se esperaba.
sed -e 's/,/"&"/' file1.txt
Respuesta1
Usando csvformat
desdecsvkit
, y suponiendo que el resultado final debe ser un archivo CSV con una coma como delimitador (como se describe en el texto de la pregunta):
$ csvformat -d '|' file
1,"a,b",4
1,"c,d",4
1,"e,f",4
1,"g,h",4
1,"i,j",4
Esto reformatea el archivo CSV para que pase de tener |
caracteres -como delimitador a tener la coma predeterminada como delimitador. Al hacerlo, cita adecuadamente los campos que necesitan citarse.
Esto también maneja adecuadamente los campos con nuevas líneas incrustadas:
$ 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
Si tiene un documento en algún formato de documento estructurado, como CSV, JSON, XML, YAML, TOML, etc., no hay ningún motivo.noutilizar un analizador para ese formato de documento para analizar ese documento.
Respuesta2
Podrías hacerlo:
awk -F'[|]' -v OFS=',' -v q='"' '{ for(i=1; i<=NF; i++) $i=q $i q }1' infile
con -F'[|]'
definimos el separador de campo de entrada.
con -v OFS=','
definimos el separador de archivos de salida.
NF
identifica cuántos campos hay en cada línea/registro según el FS (separador de campos de entrada), por lo que recorremos el número de campos y agregamos comillas dobles para cada uno de ellos e imprimimos la actualización final en la línea con1
modismo de awkpara la impresión.
tenga en cuenta que todos los campos se citan con este comando, lo que obviamente no es un problema por tener un archivo CSV válido.
Respuesta3
Con 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/[^|]*,[^|]*/"&"/g
agregue comillas dobles a todos los campos que contengan,
y/|/,/
cambiar todos|
los personajes a,
Con perl
:
perl -F'\|' -lane 'print join ",", map {/,/ ? qq("$_") : $_} @F'
Esto se utiliza |
como separador de campo de entrada. Luego map
agregará comillas dobles para todos los campos que contengan ,
. Finalmente, join
se utiliza para combinar los campos con ,
carácter.
Respuesta4
De otra sed
manera:
sed 's;\([^|]*\)|\([^|]*\)|\(.*\)$;\1,"\2",\3;' data
O si sed
admite la carga de ERE
, como por ejemplo GNU sed
, puede evitar todo el trabajo de escape:
sed -E 's;([^|]+)\|([^|]+)\|(.+)$;\1,"\2",\3;' data
Puedes aprovechar el hecho de que solo el grupo del medio está delimitado por a |
en cada límite y hacerlo sed
aún más corto:
sed 's;|\([^|]*\)|;,"\1",;' data
Por supuesto, también aquí, si su sed lo admite, -E
puede cargarlo ERE
y evitar un tedioso trabajo de escape.