Передача нескольких файлов (gz) в программу на языке Си
Вопрос
Я написал программу на языке Си, которая работает, когда я передаю данные в свою программу, используя 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
Как я могу это сделать?
Решение
Нет необходимости в цикле оболочки:
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
Другие советы
Вы должны быть в состоянии получить его 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
Это скорее вопрос оболочки.Но, АФАИК, ты можешь сделать:
cat file* | your_program
или
for i in file*; do gunzip -c $i; done | your_program
ксаргс - твой друг
% cat list.txt | архивирует файл gunzip -c | ./a.out
если в файлах в разделе list.txt есть пробелы, то вам нужно пройти через несколько дополнительных переходов.
Если вашей программе не нужно знать, когда заканчивается определенный ввод и начинается другой, вы можете сделать это:
for i `cat list.txt`
do
gunzip -c $i
done |./a.out
Я надеюсь, что это поможет вам С уважением