Cómo optimizar el script con NF y un bucle for

Tengo varios archivos, cada uno con diferente número de columnas. Quiero convertirlos para insertarlos en una base de datos

Por ejemplo, el archivo test01:

0001 000000000000001 john smith 45 500 0002 000000000000002 peter jackson 20 80 0003 000000000000002 robert brown 35 100 0004 000000000000007 sarah white 40 300 

Mi resultado deseado es:

("0001","000000000000001","john smith","45","500"), ("0002","000000000000002","peter jackson","20","80"), ("0003","000000000000002","robert brown","35","100"), ("0004","000000000000007","sarah white","40","300"); 

para lograr esto, uso el siguiente script:

cat test01 |awk -F"\t" "{print "("\"""$1""\"","\"""$2""\"","\"""$3""\"","\"""$4""\"","\"""$5""\""),"}" |sed "$ s/.$/;/" 

Y funciona bien, el problema es cuando encuentro otro archivo con un número diferente de columnas, así que tengo que modificar el script manualmente.

Sé que puedo obtener el número de columnas con la variable NF de AWK, pero ¿cómo combinar esta variable con un bucle for en el script?

Cuando intento

cat test01 | awk "{for (i = 1; i <= NF; i++){print $i""\"","\"""}}" 

obtengo este resultado:

0001"," 000000000000001"," john"," smith"," 45"," 500"," 0002"," 000000000000002"," peter"," jackson"," 20"," 80"," 0003"," 000000000000002"," robert"," brown"," 35"," 100"," 0004"," 000000000000007"," sarah"," white"," 40"," 300"," 

Comentarios

  • En el archivo original, ¿hay un delimitador de tabulación o es solo " algún espacio en blanco "?
  • Es un delimitador de tabulación

Respuesta

Usando GNU sed:

$ sed -e "s/^/("/" -e "s/\t/","/g" -e "s/$/"),/" -e "$s/.$/;/" file ("0001","000000000000001","john smith","45","500"), ("0002","000000000000002","peter jackson","20","80"), ("0003","000000000000002","robert brown","35","100"), ("0004","000000000000007","sarah white","40","300"); 

El La secuencia de comandos se divide en cuatro partes:

  1. s/^/("/ reemplaza el inicio de la línea con (".
  2. s/\t/","/g reemplaza las pestañas con ",". Este es el bit que requiere GNU sed. Para otras sed implementaciones, inserte una pestaña literal en lugar de \t.
  3. s/$/"),/ reemplaza el final de la línea con "),.
  4. $s/.$/;/ reemplaza la coma al final del última línea (solo) con ;.

Comentarios

  • Ejecuto el script y muestra " > " esperando algo
  • @ user3333911 Tenía citas que no coinciden, de una versión anterior. Corregido ahora y probado.

Respuesta

Si su archivo de entrada está separado por tabulaciones, puede intentar lo siguiente:

awk -F"\t" -vq=""" -vOFS="","" "$1=$1 {print "(" q $0 q ");"}" filename 

O inserte comillas en la función de impresión:

awk -F"\t" -vOFS="","" "$1=$1 {print "(" "\x27" $0 "\x27" ");"}" filename 

Comentarios

  • Mire las comas al final de todas las líneas excepto la última …
  • Buen aviso, @Kusalananda. Hice una solución rápida como en awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q "),"}' filename | sed '$s/,$/;/'. ¿Alguna sugerencia mejor?
  • No, esa ' es una buena solución.

Respuesta

Para alcanzar el mismo comportamiento que desea con su script inicial, puede usar el método «printf» de awk. Hace posible deshacerse de las nuevas líneas que se ponen por «imprimir». Supongo que su script debería reescribirse así:

cat test01 | awk "{for (i = 1; i <= NF; i++){printf $i""\"","\"""}; printf "\n";}" 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *