2010-03-20 2 views
0

я написал программу C, которая работает, когда данные трубы в моей программе с использованием стандартного ввода, как:Трубные несколько файлов (GZ) в программе C

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

Если я хочу, чтобы запустить свою программу в список файлы Я могу сделать что-то вроде:

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

Но это запустит мое время программы «количество файлов». Я заинтересован в передаче всех файлов в один и тот же процесс.

Как делать

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

Как я могу это сделать?

+0

Обратите внимание, что gzip поставляется с программой 'gzcat', которая эквивалентна' gunzip -c'. – greyfade

ответ

2

Там нет необходимости в петле оболочки:

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

С опцией '-cd', GZIP распаковывает список файлы на стандартный вывод (или вы можете использовать «gunzip -c»). Обозначение $(<file) расширяет содержимое именованного файла в виде списка аргументов без запуска подпроцесса. В противном случае это эквивалентно $(cat list.txt).

Однако, если вы чувствуете, что вы должны использовать цикл, то просто труба на выходе из контура в одном экземпляре вашей программы:

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

Если содержимое цикла являются более сложными (чем просто удалив один файл), это может быть необходимо.Вы также можете использовать '{ ... }' перенаправлении ввода/вывода:

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

Или:

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

Примечание полу-ободочной кишки; это необходимо с помощью брекетов. В этом примере, это по существу такой же, как с помощью формального подоболочку со скобками:

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

Или:

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

Обратите внимание на отсутствие запятой здесь; он не нужен. Корпус чудесно изогнут. Скобы Перенаправление ввода/вывода могут быть полезны, когда вам нужно сгруппировать команды после символа трубы:

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

Спасибо за все ваши прекрасные примеры очень полезной ссылки – monkeyking

2

Вы должны иметь возможность получить один gunzip процесс распаковать несколько файлов.

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

(zcat это еще один способ вызова gunzip -c на многих системах и показывает параллель с cat, но проверить gzcat, если ваша система zcat фактически uncompress.)

В качестве альтернативы вы можете использовать суб оболочку.

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

Опасайтесь: zcat изначально ассоциировался с 'pack' и 'unpack', который создавал файлы '.z'. В эти дни, они, милостиво, реликвии прошлого - они были не очень эффективны (даже меньше, чем «сжать» и «расстегнуть», которые генерировали файлы «.Z». Номинально команда, которую вы ищете, - «gzcat ', однако для zcat не является эквивалентом «gzcat». –

+0

@ Джонатан Леффлер: Хорошо, похоже, я слишком много использовал современный Linux. –

+0

Скобки вокруг цикла for являются необязательными , bash достаточно умен. –

0

Если ваша программа не нужно знать, когда конкретный вход заканчивается и начинается другая, вы можете сделать это:

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

Я надеюсь, что это поможет вам Привет

1

Это скорее вопрос оболочки. Но AFAIK вы можете сделать:

cat file* | your_program 

или

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

Это то, что я собирался напечатать, хотя для ясности были бы добавлены скобки:' (для i в файле *;. ..; сделано) | ./a.out' – crazyscot

0

xargs ваш друг

% кошка list.txt | xargs gunzip -c | ./a.out

если файлы в list.txt имеют пробелы в них, вам необходимо пройти через дополнительные обручи.

Смежные вопросы