Domanda

Ho scritto un programma in C che funziona quando il tubo di dati nel mio programma utilizzando stdin come:

gunzip -c IN.gz|./a.out

Se voglio eseguire il mio programma su un elenco di file che posso fare qualcosa di simile:

for i `cat list.txt`
do
  gunzip -c $i |./a.out
done

Ma questo farà partire il mio programma 'numero di file' volte.Mi interessa di tubazioni tutti i file nello stesso processo di esecuzione.

Come fare

for i `cat list.txt`
do
  gunzip -c $i >>tmp
done
cat tmp |./a.out

Come posso fare questo?

È stato utile?

Soluzione

Non c'è bisogno di una shell loop:

gzip -cd $(<list.txt) | ./a.out

Con il '-cd'opzione, gzip verrà decomprimere un elenco di file di output standard (o si può usare 'gunzip -c').Il $(<file) la notazione espande il contenuto del file con un nome come un elenco di argomenti, senza il lancio di un sotto-processo.È equivalente a $(cat list.txt) altrimenti.

Tuttavia, se si sente è necessario utilizzare un ciclo, quindi semplicemente il tubo di uscita dal loop in una singola istanza del programma:

for i in `cat list.txt`
do
    gunzip -c $i
done |
./a.out

Se il contenuto del ciclo sono più complesse (che semplicemente gunzipping un unico file), questa potrebbe essere necessario.È inoltre possibile utilizzare '{ ... }'I/O di reindirizzamento:

{
cat /etc/passwd /etc/group
for i in `cat list.txt`
do
    gunzip -c $i
done
} |
./a.out

O:

{
cat /etc/passwd /etc/group
for i in `cat list.txt`
do
    gunzip -c $i
done; } |
./a.out

Notare il punto e virgola;è necessario con le parentesi graffe.In questo esempio, è essenzialmente lo stesso come l'utilizzo di un formale sub-shell con le parentesi:

(
cat /etc/passwd /etc/group
for i in `cat list.txt`
do
    gunzip -c $i
done
) |
./a.out

O:

( cat /etc/passwd /etc/group
  for i in `cat list.txt`
  do
      gunzip -c $i
  done) |
./a.out

Nota l'assenza di un punto e virgola qui;non è più necessaria.La shell è meravigliosamente subdola in occasione.Le parentesi graffe reindirizzamento I/O può essere utile quando si ha bisogno di comandi di gruppo dopo il simbolo di pipe:

some_command arg1 arg2 |
{
first sub-command
second command
for i in $some_list
do
    ...something with $i...
done
} >$outfile 2>$errfile

Altri suggerimenti

Si dovrebbe essere in grado ottenere un processo gunzip decomprimere file multipli.

zcat $(cat list.txt) | ./a.out

(zcat è un altro modo di chiamare gunzip -c su molti sistemi e mostra il parallelo con cat;., Ma verificare la presenza di gzcat se zcat del sistema è in realtà uncompress)

In alternativa è possibile utilizzare una shell secondaria.

(
  for i in $(cat list.txt)
  do
    gunzip -c "$i"
  done
) | ./a.out

Questa è piuttosto una domanda shell. Ma per quanto ne so si può fare:

cat file* | your_program

o

for i in file*; do gunzip -c $i; done | your_program

xargs è tuo amico

% cat list.txt | xargs gunzip -c | ./a.out

se i file nella list.txt hanno spazi tra loro, allora avete bisogno di passare attraverso alcuni cerchi in più.

Se il programma non ha bisogno di sapere quando un particolare ingresso finisce e inizia un altro, si può fare questo:

for i `cat list.txt`
do
  gunzip -c $i
done |./a.out

Spero che vi aiuterà Saluti

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