我想使用一些预处理程序将一个目录中的文件列表转换到另一个目录中。
我知道我可以对一个文件执行此操作:
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 以便./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 脚本,充当 Web 服务器并./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
不,这是不可能的 — — 至少在没有对程序主题本身进行重写的情况下是不可能的。
目前,每个程序都要求其 stdin 中只有一个文件。它们的初始化部分或其他部分是设置与处理该单个文件相关的状态。它们执行此初始化,然后继续从 stdin 读取,直到到达“文件末尾”,然后退出。
这里有两个问题。首先,管道除了“文件结尾”(当写入器关闭其结尾时)之外没有任何其他边界。您必须设计某种特殊的同步来确定文件何时结束以及另一个文件何时开始。(也许数据包由长度 + 数据组成,空数据包标记文件结尾。)您还需要一个支持cat
此功能的自定义版本。
第二个问题是,一些项目本身,不要指望它们的 stdin 中不止一个文件。它们中的每一个都必须重写,以便 1) 理解同步方案,从而正确地将 stdin 上的多个文件分开;2) 将处理移到循环中,对于每个读取的文件;3) 在处理每个文件之前重新初始化其内存的某些部分(这在很大程度上取决于每个程序的具体功能)。
注意:您说“最后一个程序 ./program 没有这样的选项来处理目录”。我假设其他程序做有这样的选择。这意味着对于那些程序来说,#2 和 #3 是已经实施并且可以直接挂接到多文件 stdin 代码(步骤 1,您仍然需要在所有程序中实现)。