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:
-
s/^/("/
reemplaza el inicio de la línea con("
. -
s/\t/","/g
reemplaza las pestañas con","
. Este es el bit que requiere GNUsed
. Para otrassed
implementaciones, inserte una pestaña literal en lugar de\t
. -
s/$/"),/
reemplaza el final de la línea con"),
. -
$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";}"