2009-09-21 13 views
8

Potrei farlo in qualsiasi altra lingua, ma con Bash ho guardato in lungo e in largo e non ho trovato la risposta.iterazione manuale di una riga di un file | bash

Ho bisogno di aumentare manualmente $line in uno script. Esempio:

for line in `cat file` 
do 
foo() 
     foo_loop(condition) 
{ 
do_something_to_line($line) 
} 
done 

Se si nota, ogni volta che il foo_loop itera, $line rimane lo stesso. Ho bisogno di iterare $line lì, e assicurarsi che il ciclo originale for esegua solo il numero di righe nel file.

Ho pensato di trovare il numero di righe nel file utilizzando un ciclo diverso e iterando la variabile di riga all'interno del ciclo interno di foo().

Qualche idea?

EDIT:

Siamo spiacenti per essere così vago.

Qui andiamo:

Sto cercando di fare una sezione del mio codice eseguire più volte (esecuzione parallela)

Function foo() # Does something 
for line in `cat $temp_file`; 
foo($line) 

Questo codice funziona bene, perché foo è solo prendendo in valore della linea; ma se volevo fare questo:

Function foo() # Does something 
for line in `cat $temp_file`; 
while (some condition) 
foo($line) 
end 

$line sarà uguale lo stesso valore in tutto il ciclo while. Ho bisogno che cambi con il ciclo while, quindi continui quando torna allo for. Esempio:

line = Hi 
foo{ echo "$line" }; 
for line in `cat file`; 
while (number_of_processes_running -lt max_number_allowed) 
foo($line) 
end 

Se il contenuto del file sono state

Hi \n Bye \n Yellow \n Green \n 

L'uscita del programma di esempio potrebbe essere (se il numero massimo consentito era 3)

Hi Hi Hi Bye Bye Bye Yellow Yellow Yellow Green Green Green. 

Dove voglio che be

Hi Bye Yellow Green 

Spero questo è meglio. Sto facendo del mio meglio per spiegare il mio problema.

+0

Penso che abbiamo bisogno di un esempio più chiaro di ciò che stai cercando di realizzare. pippo() sembra definire una funzione di shell all'interno di un ciclo, che non sono sicuro sia ciò che si desidera. –

risposta

16

Invece di utilizzare un ciclo for per leggere il file, è consigliabile leggere il file in questo modo.

#!bin/bash 

while read line 
do 
    do_something_to_line($line) 
done < "your.file" 
+0

Si noti che questo non funzionerà per le linee con barre retroverse (leggi rimosse) e per gli spazi bianchi iniziali e/o finali (rimossi). Il modo corretto è usare 'read -r line' per evitare la rimozione di backslash e per impostare' IFS = 'per evitare la rimozione dello spazio bianco. – Jens

6

Per farla breve, while read line; do _____ ; done

Quindi, assicuratevi di avere virgolette intorno "$ riga" in modo che un parametro non è delimitato da spazi.

Esempio:

$ cat /proc/cpuinfo | md5sum 
c2eb5696e59948852f66a82993016e5a *- 

$ cat /proc/cpuinfo | while read line; do echo "$line"; done | md5sum 
c2eb5696e59948852f66a82993016e5a *- 

Secondo esempio # aggiungono.gz ad ogni file nella directory corrente: # Se qualche file ha spazi, il comando mv per quella riga restituirebbe un errore.

$ find -type f -maxdepth 1 | while read line; do mv "$line" "$line.gz"; done 
+1

-1 per l'uso inutile di cat. Sapevi che puoi reindirizzare anche a comandi composti? 'mentre leggi ...; fare ...; fatto Jens

1

È necessario postare post-it come modifiche alla propria domanda o nei commenti anziché come risposta.

Questa struttura:

while read line 
do 
    for ((i=1; i<$max_number_allowed; i++)) 
    do 
     foo $line 
    done 
done < file 

Resa:

Hi 
Hi 
Hi 
Bye 
Bye 
Bye 
...etc.

mentre questo:

for ((i=1; i<$max_number_allowed; i++)) 
do 
    while read line 
    do 
     foo $line 
    done < file 
done 

Resa:

Hi 
Bye 
Yellow 
Green 
Hi 
Bye 
Yellow 
Green 
...etc.
Problemi correlati