Frage

Ich habe ein C-Programm geschrieben, das funktioniert, wenn ich Rohrdaten in mein Programm mit stdin wie:

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

Wenn ich mein Programm auf einer Liste von Dateien ausführen ich etwas tun kann, wie:

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

Aber das wird mein Programm ‚Anzahl der Dateien‘ mal starten. Ich bin daran interessiert, alle Dateien in den gleichen Prozess laufen in Rohrleitungen.

Wie tun

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

Wie kann ich das tun?

War es hilfreich?

Lösung

Es besteht keine Notwendigkeit für eine Shell-Schleife:

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

Mit der ‚-cd‘ Option, gzip wird eine Liste der Dateien auf der Standardausgabe dekomprimieren (oder Sie verwenden können ‚gunzip -c‘). Die $(<file) Notation erweitert den Inhalt der Datei mit dem Namen als Liste von Argumenten, ohne einen Teilprozess zu starten. Es entspricht ansonsten $(cat list.txt).

Wenn Sie jedoch das Gefühl haben eine Schleife verwenden müssen, dann einfach Rohr die Ausgabe von der Schleife in einer einzigen Instanz des Programms:

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

Wenn der Inhalt der Schleife komplexer ist (als nur eine einzelne Datei gunzip), könnte dies erforderlich sein. Sie können auch '{ ... }' verwenden I / O-Umleitung:

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

Oder:

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

Beachten Sie das Semikolon; ist es notwendig, mit Klammern. In diesem Beispiel ist es im Wesentlichen der gleiche wie eine formale Unterschale mit Klammern verwenden:

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

Oder:

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

Beachten Sie das Fehlen eines Semikolons hier; es ist nicht erforderlich. Die Schale ist wunderbar verschlagen gelegentlich. Die Streben I / O-Umleitung kann nützlich sein, wenn Sie gruppieren Befehle nach dem Pipe-Symbol müssen:

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

Andere Tipps

Sie sollten unzip mehrere Dateien können get ein gunzip Prozess sein.

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

(zcat ist eine andere Art und Weise gunzip -c auf vielen Systemen und zeigt die parallel mit cat aufzurufen;., Aber überprüfe für gzcat wenn Ihr System zcat tatsächlich uncompress ist)

Alternativ können Sie eine Unterschale verwendet werden.

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

Dies ist eher eine Schale Frage. Aber AFAIK Sie tun können:

cat file* | your_program

oder

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

xargs ist dein Freund

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

, wenn die Dateien in list.txt Leerzeichen in ihnen dann müssen Sie durch einige zusätzliche Reifen gehen.

Wenn Ihr Programm nicht wissen müssen, wenn ein bestimmtes Eingangsenden und ein andere beginnen, können Sie dies tut:

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

Ich hoffe, es wird Ihnen helfen, Grüße

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top