Domanda

Sto tentando di convertire le date da un formato ad un altro:Per esempio"29 ottobre 2005" per 2005-10-29.Ho un elenco di 625 date.Io uso Awk.

La conversione funziona-la maggior parte del tempo.Ma io, a volte la conversione non capita a tutti, e la variabile dovrebbe tenere l' (convertito) data rimane non definito.

Questo accade sempre con le stesse righe.L'esecuzione di `data' esplicitamente (dalla shell Bash) nelle date di di quelle strane righe funziona bene (le date sono opportunamente convertiti).- Non è il contenuto testuale di quelle righe che conta.

Perché di questo comportamento e come posso risolvere il mio script?
Lei è:

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

Se si desidera riprodurre il problema:

  1. Scarica questo file: uBXr0r15.txt.
  2. Eseguire lo script Awk.
  3. Ricerca di "indefinito" in bug-out-3.txt.
    ("undefined" trovati 122 volte, sul mio computer).

Quindi è possibile eseguire nuovamente lo script, e (sul mio computer) bug-out-3.txt rimane invariato-esattamente la stesse date sono lasciati indefiniti.

(Gawk versione 3.1.6, Ubuntu 9.10.)

Cordiali saluti, Magnus

È stato utile?

Soluzione

Ogni volta che si apre un tubo o un file per la lettura o la scrittura in awk, l'ultimo innanzitutto controlla (utilizzando un hash interno) se si dispone già di un tubo o un file con lo stesso nome (ancora) aperta;se è così, esso è in grado di riutilizzare l'esistente descrittore di file invece di riaprire il tubo o il file.

Nel tuo caso, tutte le voci che finiscono undefined in realtà sono duplicati;la prima volta che si sono incontrati (es.quando il comando corrispondente date "..." -d "..." è rilasciato per la prima volta) il risultato corretto è leggere in x.Nelle successive occorrenze della stessa data, getline tenta di leggere un secondo, terzo e così via.linee originali date il tubo, anche se il tubo è stato chiuso da date, con conseguente x non è più assegnato.

Dal gawk uomo-pagina:

NOTA:Se si utilizza un tubo, co-processo, o presa per getline, o da stampare o printf all'interno di un ciclo, è necessario utilizzare close() per creare nuove le istanze di comando o socket.AWK non automaticamente chiudere i tubi, prese di corrente, o co-processi quando si ritorna EOF.

In modo esplicito close il tubo ogni volta dopo aver letto x:

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

Per inciso, sarebbe OK per sort e uniq uBXr0r15.txt prima di tubazioni in awk, o avete bisogno di ordinamento originale/duplicazione?

Altri suggerimenti

Anche se io amo il awk non è necessario per questo.

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

facendo tutto all'interno di gawk sarà più chiamata comandi esterni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top