Comment optimiser le script avec NF et une boucle for

Jai plusieurs fichiers, chacun avec un nombre de colonnes différent. Je veux les convertir pour les insérer dans une base de données

Par exemple le fichier 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 

Ma sortie souhaitée est:

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

pour y parvenir, jutilise le script suivant:

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

Et cela fonctionne bien, le problème est quand je trouve un autre fichier avec un nombre de colonnes différent, donc je dois modifier le script manuellement.

Je sais que je peux obtenir le nombre de colonnes avec la variable NF de lAWK, mais comment combiner cette variable avec une boucle for dans le script?

Quand jessaye

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

Jobtiens ce résultat:

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

Commentaires

  • Dans le fichier dorigine, y a-t-il un délimiteur de tabulation ou est-ce simplement " des espaces "?
  • Cest un délimiteur donglet

Réponse

Utilisation de 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"); 

Le est en quatre parties:

  1. s/^/("/ remplace le début de la ligne par (".
  2. s/\t/","/g remplace les onglets par ",". Cest le bit qui nécessite GNU sed. Pour les autres implémentations de sed, insérez une tabulation littérale à la place de \t.
  3. s/$/"),/ remplace la fin de la ligne par "),.
  4. $s/.$/;/ remplace la virgule à la fin du dernière ligne (uniquement) avec ;.

Commentaires

  • Je lance le script et il invite " > " en attente de quelque chose
  • @ user3333911 Javais des citations incohérentes, dune version antérieure. Corrigé maintenant et testé.

Réponse

Si votre fichier dentrée est séparé par des tabulations, vous pouvez essayer ce qui suit:

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

Ou incorporer des guillemets dans la fonction dimpression:

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

Commentaires

  • Regardez les virgules à la fin de toutes les lignes sauf pour la dernière …
  • Bonne remarque @Kusalananda. Jai fait une solution rapide comme dans awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q "),"}' filename | sed '$s/,$/;/'. Une meilleure suggestion?
  • Non, cette ' est une bonne solution.

Réponse

Pour atteindre le même comportement que vous le souhaitez avec votre script initial, vous pouvez utiliser la méthode « printf » de awk. Il permet de se débarrasser des retours à la ligne qui sont mis par « print ». Je suppose que votre script devrait être réécrit comme ceci:

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

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *