2012-09-05 5 views
5

Centos/Linux Bash sed: massa conversione epoche tra l'altro testo casuale

Ho un file di log, che ha un sacco di testo e numeri in epoca in tutto il luogo. Voglio sostituire tutte le epoche dovunque siano in data/ora leggibili.

Ho voluto questo via tramite sed, come sembra lo strumento per il lavoro. Non riesco a ottenere la parte di ricambio di sed per analizzare effettivamente la variabile (epoca) ad essa per la conversione.

Esempio di quello che sto lavorando con ...

echo "Some stuff 1346474454 And not working" \ 
| sed 's/1[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/'"`bpdbm -ctime \&`"'/g' 
Some stuff 0 = Thu Jan 1 01:00:00 1970 And not working 

La parte bpdbm ​​convertirà una variabile un'epoca in dotazione nella data utile. Mi piace ..

bpdbm -ctime 1346474454 
1346474454 = Sat Sep 1 05:40:54 2012 

Così come faccio ad analizzare l'elemento "trovato" in un comando. Come non sembra essere in grado di farlo funzionare.

Qualsiasi aiuto sarebbe bello. Se c'è un altro modo, sarebbe bello ... ma sospetto che sed sarà più veloce.

Grazie per il vostro tempo!

+0

esegui questo con 'set -vx' per capire perché non funziona.Sed deve elaborare la riga di dati prima che "sappia" il valore di "&", la sottotitolazione di cmd dovrebbe essere ritardata fino all'ultima cosa, ma è probabile che la prima cosa che viene elaborata. Puoi farlo facilmente in awk. La tua fiducia in sed è commovente ;-). In bocca al lupo! – shellter

+0

Beh, sì ... piacerebbe provare e continuare a sed e awk dove possibile. Avrà un altro gioco con Sed domani, non ho rinunciato a una risoluzione basata su sed – user1649704

risposta

7

che sembra lo strumento per il lavoro

No, non lo è. sed può utilizzare solo &, non c'è modo di renderlo un argomento per un comando. Hai bisogno di qualcosa di più potente, ad es. Perl:

perl -pe 'if (($t) = /(1[0-9]+)/) { s/$t/localtime($t)/e }' 
+0

Che funziona meravigliosamente, grazie !! – user1649704

+0

Questo ha funzionato perfettamente per me per l'analisi dell'XML che aveva un tempo epocale in termini leggibili: 'cat inputfile.xml | perl -pe 'if (($ t) =/(1 [0-9] +) /) {s/$ t/localtime ($ t)/e}'> outputfile.xml' – zedix

1

si può fare con GNU sed, l'ingresso:

infile

Some stuff 1346474454 And not working 

GNU sed supporta /e parametro che permette di output del comando tubazioni nello spazio modello, uno modo per approfittare di questo con bpdbm:

sed 's/(.*)(1[0-9]{9})(.*)/echo \1 $(bpdbm -ctime \2) \3/e' infile 

O con coreutilsdate:

sed 's/(.*)(1[0-9]{9})(.*)/echo \1 $(date -d @\2) \3/e' infile 

uscita con la data

Some stuff Sat Sep 1 06:40:54 CEST 2012 And not working 

Per ottenere lo stesso risultato con bpdbm:

sed 's/(.*)(1[0-9]{9})(.*)/echo "\1$(date -d @\2 +\"%a %b %_d %T %Y\")\3"/e' infile 

uscita

Some stuff Sat Sep 1 06:40:54 2012 And not working 

Nota, questo sostituisce solo l'ultima epoca trovata su una linea. Rieseguire se ce ne sono altri.