Question

J'ai écrit un programme C qui fonctionne quand je les données de conduite dans mon programme en utilisant stdin comme:

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

Si je veux lancer mon programme sur la liste des fichiers que je peux faire quelque chose comme:

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

Mais cela va commencer mon programme "nombre de fichiers de fois. Je suis intéressé par la tuyauterie tous les fichiers dans le même cycle de processus.

Comme faire

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

Comment puis-je faire?

Était-ce utile?

La solution

Il n'y a pas besoin d'une boucle shell:

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

Avec l'option « -cd », gzip décompresse une liste de fichiers à la sortie standard (ou vous pouvez utiliser « gunzip -c »). La notation $(<file) élargit le contenu du fichier nommé une liste d'arguments sans lancer un sous-processus. Il est équivalent à $(cat list.txt) autrement.

Cependant, si vous sentez que vous devez utiliser une boucle, puis conduit simplement la sortie de la boucle en une seule instance de votre programme:

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

Si le contenu de la boucle sont plus complexes (que simplement de décompresser un seul fichier), cela pourrait être nécessaire. Vous pouvez également utiliser '{ ... }' redirection 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

Notez le point-virgule; il est nécessaire avec des accolades. Dans cet exemple, il est essentiellement identique à l'aide d'un sous-shell formelle avec des parenthèses:

(
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

Notez l'absence d'un point-virgule ici; il est pas nécessaire. La coquille est merveilleusement sournoise à l'occasion. Les accolades redirection E / S peut être utile lorsque vous avez besoin de regrouper les commandes après le symbole de la conduite:

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

Autres conseils

Vous devriez pouvoir obtenir un processus de gunzip décompressez plusieurs fichiers.

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

(zcat est une autre façon d'appeler gunzip -c sur de nombreux systèmes et montre le parallèle avec cat;. Mais pour vérifier si votre gzcat zcat du système est en fait uncompress)

Sinon, vous pouvez utiliser un shell sous.

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

Ceci est plutôt une question de la coquille. Mais vous pouvez faire autant que je sache:

cat file* | your_program

ou

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

xargs est votre ami

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

si les fichiers list.txt ont des espaces en eux, alors vous devez passer par des cerceaux supplémentaires.

Si votre programme n'a pas besoin de savoir quand une entrée particulière se termine et un autre commence, vous pouvez faire ceci:

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

J'espère que cela vous aidera Cordialement

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top