Pergunta

Eu escrevi um programa C que funciona quando coloco dados no meu programa usando o stdin como:

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

Se eu quiser executar meu programa em uma lista de arquivos, posso fazer algo como:

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

Mas isso iniciará o número de horários dos arquivos do meu programa. Estou interessado em expor todos os arquivos para o mesmo processo executado.

Como fazer

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

Como posso fazer isso?

Foi útil?

Solução

Não há necessidade de um loop de concha:

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

Com o '-cd'Opção, o GZIP descompactará uma lista de arquivos para saída padrão (ou você pode usar'gunzip -c'). o $(<file) A notação expande o conteúdo do arquivo nomeado como uma lista de argumentos sem iniciar um subprocesso. É equivalente a $(cat list.txt) por outro lado.

No entanto, se você sentir que deve usar um loop, basta colocar a saída do loop em uma única instância do seu programa:

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

Se o conteúdo do loop for mais complexo (do que simplesmente atirar um único arquivo), isso pode ser necessário. Você também pode usar '{ ... }'Redirecionamento de E/S:

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

Ou:

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

Observe o Semi-Colon; é necessário com aparelho. Neste exemplo, é essencialmente o mesmo que usar uma sub-concha formal com parênteses:

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

Ou:

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

Observe a ausência de um Semi-Colon aqui; não é necessário. A concha é maravilhosamente desonesta de vez em quando. O redirecionamento de E/S do aparelho pode ser útil quando você precisar agrupar comandos após o símbolo do tubo:

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

Outras dicas

Você deve poder conseguir um gunzip Processe descompacte vários arquivos.

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

(zcat é outra maneira de ligar gunzip -c em muitos sistemas e mostra o paralelo com cat; mas verifique gzcat Se o seu sistema zcat é na verdade uncompress.)

Como alternativa, você pode usar um sub shell.

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

Esta é uma questão de concha. Mas Afaik você pode fazer:

cat file* | your_program

ou

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

Xargs é seu amigo

% Cat List.txt | XARGS Gunzip -C | ./a.out

Se os arquivos no list.txt tiverem espaços neles, você precisará passar por alguns aros extras.

Se o seu programa não precisar saber quando uma entrada específica termina e outro começa, você pode fazer isso:

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

Espero que isso ajude você a cumprir

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top