Pipe varios archivos (GZ) en el programa C
Pregunta
He escrito un programa en C que funciona cuando los datos de E tubo en mi programa usando la entrada estándar como:
gunzip -c IN.gz|./a.out
Si quiero correr mi programa en una lista de archivos que puedo hacer algo como:
for i `cat list.txt`
do
gunzip -c $i |./a.out
done
Pero esto comenzará mi programa 'Cantidad de archivos' tiempos. Estoy interesado en la tubería de todos los archivos en la misma corrida proceso.
Como hacer
for i `cat list.txt`
do
gunzip -c $i >>tmp
done
cat tmp |./a.out
¿Cómo puedo hacer esto?
Solución
No hay necesidad de un bucle de shell:
gzip -cd $(<list.txt) | ./a.out
Con la opción '-cd
', gzip descomprimirá una lista de archivos en la salida estándar (o puede utilizar 'gunzip -c
'). La notación $(<file)
amplía el contenido del archivo con el nombre de una lista de argumentos sin necesidad de iniciar un sub-proceso. Es equivalente a $(cat list.txt)
lo contrario.
Sin embargo, si usted siente que debe usar un bucle, a continuación, simplemente canalizar la salida del bucle en una sola instancia de su programa:
for i in `cat list.txt`
do
gunzip -c $i
done |
./a.out
Si el contenido del bucle es más compleja (que simplemente a descomprimir un archivo único), esto podría ser necesario. También puede utilizar '{ ... }
' I / O redirección:
{
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
Tenga en cuenta el punto y coma; es necesario con los apoyos. En este ejemplo, es esencialmente el mismo que el uso de un sub-shell formal con paréntesis:
(
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
Tenga en cuenta la ausencia de un punto y coma aquí; no se necesita. La cáscara es maravillosamente tortuosa en la ocasión. Los tirantes de E / S de redirección puede ser útil cuando se necesita agrupar los comandos después de que el símbolo de canalización:
some_command arg1 arg2 |
{
first sub-command
second command
for i in $some_list
do
...something with $i...
done
} >$outfile 2>$errfile
Otros consejos
Usted debe ser capaz de obtener un solo proceso gunzip
descomprimir varios archivos.
zcat $(cat list.txt) | ./a.out
(zcat
es otra forma de llamar a gunzip -c
en muchos sistemas y muestra el paralelismo con cat
;. Pero la salida de gzcat
si zcat
de su sistema es en realidad uncompress
)
Alternativamente, puede utilizar una cáscara sub.
(
for i in $(cat list.txt)
do
gunzip -c "$i"
done
) | ./a.out
Esto es más bien una cuestión shell. Pero yo sepa que puede hacer:
cat file* | your_program
o
for i in file*; do gunzip -c $i; done | your_program
xargs es su amigo
% list.txt gato | xargs gunzip -c | ./a.out
si los archivos en list.txt tienen espacios en ellos, entonces usted necesita para ir a través de unos aros adicionales.
Si el programa no necesita saber cuándo una entrada particular termina y comienza otro, usted puede hacer esto:
for i `cat list.txt`
do
gunzip -c $i
done |./a.out
Espero que le ayudará Saludos