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