Передача нескольких файлов (gz) в программу на языке Си

StackOverflow https://stackoverflow.com/questions/2485057

  •  21-09-2019
  •  | 
  •  

Вопрос

Я написал программу на языке Си, которая работает, когда я передаю данные в свою программу, используя 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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top