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

Я знаю, что могу сделать это для одного файла:

cat "$INDIR/$file" | ./program > "$OUTDIR/$file"

И я знаю, что могу сделать это для нескольких файлов:

for file in $(ls -1 $INDIR); do
    cat "$INDIR/$file" | ./program > "$OUTDIR/$file";
done

Но проблема в том, что ./program требуется довольно много времени для инициализации, и я не хочу, чтобы эти издержки повторялись, так как внутри $INDIR будет много файлов, и мой подход выше всегда перезапускает ./program для каждого файла в каталоге. Это медленно.

Итак, мой вопрос: есть ли способ выполнить мою задачу выше без повторной инициализации ./program в bash?

(отредактируйте после @grawity) Понимая, что мы не можем просто передать все файлы за один раз, перейдите в stdin of ./program чтобы иметь возможность разделить вывод, я ожидаю, что у меня будет возможность создать функцию create_into_pipeline которая выполняет что-то вроде этот:

process_pipeline = create_into_pipeline(./program.pl | ./program.py | ./program.bash | ./program);
for file in $(ls -1 $INDIR); do
    process_pipeline < cat "$INDIR/$file" > "$OUTDIR/$file.new";
done

Если это невозможно, то, я думаю, я пойду с созданием скрипта Python, который будет действовать как веб-сервер, и вызовом ./program если это необходимо. Но я хочу знать, смогу ли я сделать это в bash, поскольку я считаю, что в bash это будет более эффективным по времени, чем в Python (вы также можете доказать это неправильно, и я продолжу работу с Python).


Еще немного деталей

На самом деле ./program - это последовательность программ, передаваемых друг другу, как таковая:

./program.pl | ./program.py | ./program.bash | ./program

Я рассмотрел каждую программу, чтобы использовать опцию для обработки одного каталога файлов и вывода в другой каталог, сохраняя имена файлов. Но поскольку у меня там четыре программы, я не хочу создавать три временных каталога, так как доступ к жесткому диску будет медленным. Итак, я не хочу этого:

./program.pl $INDIR $OUTDIR;
./program.py $INDIR $OUTDIR;
./program.bash $INDIR $OUTDIR;
./program $INDIR $OUTDIR;

Просто дополнительная информация на случай, если это может изменить ответ (и фактически последняя программа ./program не имеет такой возможности для обработки каталога, поэтому я все равно не могу использовать этот подход).

1 ответ1

2

Нет, это невозможно - по крайней мере, без переписывания тем программ.

В настоящее время каждая из ваших программ ожидает в своем стандартном файле ровно один файл. Некоторая или другая часть их инициализации устанавливает состояние, относящееся к обработке этого отдельного файла. Они выполняют эту инициализацию, затем продолжают чтение из стандартного ввода, пока не достигнут "конец файла", затем завершают работу.

Здесь есть две проблемы. Во-первых, канал не имеет никаких других границ, кроме "конца файла" (когда пишущий закрывает свой конец). Вам нужно будет разработать какую-то специальную синхронизацию, чтобы определить, когда заканчивается файл и начинается другой файл. (Возможно пакеты, состоящие из длины + данные, с пустым пакетом, отмечающим конец файла.) Вам также понадобится специальная версия cat которая поддерживает это.

Вторая проблема заключается в том, что некоторые из программ сами по себе не ожидают более одного файла в своем stdin. Каждый из них должен быть переписан так: 1) понимать схему синхронизации для правильного разделения нескольких файлов на stdin; 2) переместить обработку в цикл для каждого прочитанного файла; 3) реинициализировать часть своей памяти перед обработкой каждого файла (это во многом зависит от того, что именно делает каждая программа).

Примечание. Вы говорите, что «последняя программа ./program не имеет такой возможности для обработки каталога». Я полагаю , что другие программы не имеют такой вариант. Это означает, что для этих программ # 2 и # 3 уже реализованы и могут быть просто подключены к многофайловому стандартному коду (шаг # 1, который вам все еще нужно реализовать во всех программах).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .