Передача нескольких файлов (gz) в программу C - PullRequest
0 голосов
/ 21 марта 2010

Я написал программу на C, которая работает, когда я передаю данные в свою программу, используя stdin, например:

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

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

Ответы [ 5 ]

2 голосов
/ 21 марта 2010

Нет необходимости в цикле оболочки:

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
2 голосов
/ 21 марта 2010

Вы сможете получить один 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
1 голос
/ 21 марта 2010

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

cat file* | your_program

или

for i in file*; do gunzip -c $i; done | your_program
0 голосов
/ 28 марта 2010

XARGS твой друг

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

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

0 голосов
/ 21 марта 2010

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

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

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

...