2011-01-25 9 views
7

Ho un array di valori $dates che sto trasformando:unix funzione mappa

for i in $dates 
do 
    date -d "1970-01-01 $i sec UTC" '+%a_%D' 
done 

C'è un modo per salvare il risultato di questa operazione in modo che posso pipe a qualcosa d'altro, senza scriverlo in un file su disco?

+2

Sei limitato a bash? In caso contrario, consiglierei di farlo in Perl ... la mappa viene fornita come parte del pacchetto. – DVK

+0

Quanto è grande il tuo array? 10s, 100s, 1000s, più grande? Perché non può essere scritto su disco? Puoi tenere i risultati in un altro array? Perchè no? –

+0

La tua versione di 'date' supporta' date -d "@ $ i" '+% a_% D''? –

risposta

6

Creare una funzione:

foo() { 
     for i in [email protected] 
     do 
       date -d "1970-01-01 $i sec UTC" '+%a_%D' 
     done 
} 

Quindi è possibile per esempio inviare l'output sullo standard error:

echo `foo $dates` >&2 
+0

Che cosa fa per te inviare l'output all'errore standard? Potresti farlo senza una funzione: 'for ... done> & 2'. –

+0

@Dennis Williamson: non si tratta di inviare l'output a stderr; quello era solo un esempio di come usare la funzione. Si tratta di essere in grado di catturare l'output senza fare troppe espressioni lunghe come '$ (per i in $ date; do date -d" @ $ i "'+% a_% D'; done)' sempre. – Oswald

+0

I '$ (...)' non sono necessari. Puoi sondare l'intero 'for' come ha mostrato Dennis. Come in "per ... fatto | 2 °-comando'. – Adrian

2

Si potrebbe scrivere su una FIFO, una "named pipe" che sembra un file.

Wikipedia ha un esempio decente del suo uso: http://en.wikipedia.org/wiki/Named_pipe

+0

I pipe denominati sono davvero interessanti, grazie! Continuo a ottenere un punto morto, però. Hai bisogno di saperne di più su di loro. – pokerface

3

La tua domanda è un po 'vago, ma il seguente potrebbe funzionare:

for ... 
do 
... 
done | ... 
1

Modifica, non ha visto il tutto di file:

for i in $dates ; do 
    date -d "1970-01-01 $i sec UTC" '+%a_%D' 
done |foo 
+0

L'op specificamente menzionato non vuole scrivere i dati in un file. –

+0

La risposta 2 con il singolo reindirizzamento I/O deve essere utilizzata anziché l'append-per-command nella risposta 1. –

1

Se si utilizza bash, è possibile utilizzare un array:

q=0 
for i in $dates 
do 
    DATEARRAY[q]="$(date -d "1970-01-01 $i sec UTC" '+%a_%D')" 
    let "q += 1" 
done 

È quindi possibile echo/pipe quella matrice in un altro programma. Nota che gli array sono bash specifici, il che significa che non si tratta di una soluzione portatile (bene, al di là dei sistemi che hanno una base).

+0

Non è necessario sfuggire alle virgolette all'interno di '$()'. Sono valutati separatamente da quelli esterni. In effetti, in questo caso non funzionerà. Puoi fare 'array + = (elemento)' e non devi tenere traccia di una variabile indice. –

+0

Gli array esistono nella maggior parte delle shell, ed erano in csh per primi, con quasi la stessa sintassi ('set DATEARRAY [q] = ...'). –

+0

@Dennis - Grazie, in realtà li ho aggiunti come ripensamenti. @ Charles, non credo che esistano in dash, ksh, pdksh o busybox (che è fondamentalmente dash iirc), da qui l'avvertenza per la portabilità. Neat per sapere che erano in csh prima, che non riesco a usare _nearly_ abbastanza :) –

11

Dal momento che si dice "trasformare" Sto assumendo vuoi dire che si desidera catturare l'output del ciclo in una variabile. È anche possibile sostituire il contenuto della variabile $dates.

dates=$(for i in $dates; do date -d "@$i" '+%a_%D'; done) 
+0

Sono stato ispirato da questo e ho usato 'bless $ (per i in {0..127}; do printf '0x% 06x' $ (($ i * 0x4000)); done)' per aprire molti file '0x000000, 0x004000 , 0x008000, 0x00c000, 0x010000, 0x014000, ... 'contemporaneamente in ordine logico. –

Problemi correlati