es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Leyendo una cadena csv en un array de bash

La siguiente función utiliza awk para convertir una línea de csv en múltiples líneas. Luego puedo asignar la salida a un arreglo para poder acceder a los campos.

function csv<em>to</em>lines() {
echo $@ | awk '
BEGIN {FPAT = "([^,]*)|(\"[^\"]+\")";}
{for(i=1; i<=NF; i++) {printf("%s\n", $i)}}'
}

line='A,B,"C,D",E'
arr=($(csv<em>to</em>lines $line))

printf '%s,' "${arr[@]}"

Sin embargo, esto no funciona para campos vacíos. Por ejemplo:

line='A,,,,,"C,D",E'
arr=($(csv<em>to</em>lines $line))`

`printf '%s,' "${arr[@]}"

La salida es A,"C,D",E, pero yo esperaba A,,,,,"C,D",E,

Evidentemente, todas las líneas vacías se ignoran al asignar al arreglo. ¿Cómo puedo crear un arreglo que mantenga las líneas vacías?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para crear una matriz que mantenga las líneas vacías, puede modificar la función csv_to_lines para agregar una comprobación de campos vacíos y reemplazarlos por un marcador antes de asignarlos a la matriz. Aquí hay una versión actualizada de la función:

    function csv_to_lines() {
    echo $@ | awk '
    BEGIN {FPAT = "([^,]*)|(\"[^\"]+\")";}
    {
      for(i=1; i<=NF; i++) {
        if ($i == "") {
          printf("_BLANK_ ");
        } else {
          printf("%s ", $i);
        }
      }
    }'
    }
    
    line='A,,,,,"C,D",E'
    arr=($(csv_to_lines "$line"))
    
    for i in "${arr[@]}"
    do
      if [ $i == "_BLANK_" ]
      then
        printf ", "
      else
        printf "%s, " "$i"
      fi
    done
    

    La función actualizada verifica campos vacíos ($i == "") e imprime un marcador (_BLANK_) en su lugar. El marcador puede ser cualquier cadena que sea poco probable que aparezca en los datos de entrada. La función csv_to_lines luego reemplaza los campos vacíos con el marcador _BLANK_ antes de asignarlos a la matriz.

    En el bucle for que imprime los elementos de la matriz, verificamos el marcador _BLANK_ e imprimimos una coma en lugar de omitir el elemento. De esta manera, los campos vacíos se conservan en la salida.

    Con la función actualizada, la línea de entrada 'A,,,,,"C,D",E' producirá la salida esperada:

    A, _BLANK_, _BLANK_, _BLANK_, _BLANK_, "C,D", E,
    

Comments are closed.