Question

Je tente de convertir les dates d'un format à l'autre: De par exemple « .29 Octobre 2005 » Représenter 2005-10-29. J'ai une liste de 625 dates. J'utilise awk.

Les travaux de conversion - la plupart du temps. Hovewer, parfois la conversion ne se produira pas du tout, et la variable censée contenir les restes de date (convertis) non défini.

Cela se produit toujours avec exactement les mêmes lignes. Exécution `date » explicitement (à partir du shell Bash) sur les dates de ces lignes étranges fonctionne très bien (les dates sont correctement converties). -. Ce n'est pas le contenu textuel de ces lignes qui compte

Pourquoi ce comportement, et comment puis-je réparer mon script?
Son est:

awk 'BEGIN { FS = "unused" } { 
  x = "undefined";
  "date \"+%Y-%m-%d\" -d " $1 | getline x ;
  print $1 " = " x
}' uBXr0r15.txt \
 > bug-out-3.txt

Si vous voulez reproduire ce problème:

  1. Télécharger ce fichier:. uBXr0r15.txt
  2. Lancez le skript Awk.
  3. Rechercher "undefined" dans le bogue-out-3.txt.
    (Trouvé 122 fois "non défini", sur mon ordinateur.)

Ensuite, vous pouvez exécuter à nouveau le script,   et (sur mon ordinateur) reste bug-out-3.txt   inchangé -. exactement les mêmes dates sont laissées undefined

(version 3.1.6 Gawk, Ubuntu 9.10.)

Cordialement, Magnus

Était-ce utile?

La solution

Chaque fois que vous ouvrez un tube ou d'un fichier pour la lecture ou l'écriture dans awk, ce dernier va d'abord vérifier (en utilisant un hachage interne) si elle a déjà un tuyau ou un fichier avec le même nom (encore) ouvert; le cas échéant, il réutiliser le descripteur de fichier existant au lieu de rouvrir le tuyau ou d'un fichier.

Dans votre cas, toutes les entrées qui finissent comme undefined sont des doublons en fait; la première fois qu'ils sont rencontrés (à savoir lorsque le date "..." -d "..." de commande correspondant est d'abord émis) le résultat correct est lu dans x. Sur les occurrences suivantes de la même date, getline tente de lire un deuxième, troisième lignes, etc. de la conduite de date d'origine, même si le tube a été fermé par date, ce qui x ne sont plus affectés.

De l'homme gawk page:

  

Remarque: Si l'on utilise un tuyau, co-processus, ou d'une douille à getline, ou   d'impression ou printf dans une boucle,   vous devez utiliser close () pour créer un nouveau   cas de la commande ou de la douille. AWK ne pas automatiquement   tubes étroits, des douilles, ou de co-processus   quand ils reviennent EOF.

Vous devez close explicitement le tuyau à chaque fois après avoir lu x:

close("date \"+%Y-%m-%d\" -d " $1)

Soit dit en passant, serait-il sur OK pour sort et uniq uBXr0r15.txt avant la tuyauterie en awk, ou avez-vous besoin de la commande / duplication original?

Autres conseils

Bien que je l'aime awk il ne faut pas pour cela.

tr -d '"' < uBXr0r15.txt | date +%Y-%m-%d -f -

 gawk 'BEGIN{
       m=split("January|February|March|April|May|June|July|August|September|October|November|December",d,"|")
       for(o=1;o<=m;o++){
          months[d[o]]=sprintf("%02d",o)
       }
       FS="[, ]"
    }
    {
      gsub(/["]/,"",$1)
      gsub(/["]/,"",$4)
      t=mktime($4" "months[$1]" "$2" 0 0 0")
      print strftime("%Y-%m-%d",t)
    }' uBXr0r15.txt

faire tout ce que l'intérieur gawk sera plus rapide que d'appeler des commandes externes.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top