Rohr mehrere Dateien (gz) in C-Programm
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?
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