将多个文件的内容提供给脚本的标准输入的简写

将多个文件的内容提供给脚本的标准输入的简写

假设我有一个名为 的脚本script,它读取stdin一些结果并将其输出到屏幕上。

如果我想向它提供一个文件的内容,我会输入:

$ ./script < file1.txt

但是,如果我想以相同的方式将多个文件的内容提供给脚本,这可能吗?到目前为止我想出的最好的办法是:

cat file1.txt file2.txt > combined.txt && ./script < combined.txt

它使用两个命令并创建一个临时文件。有没有办法做同样的事情但绕过创建组合文件?

答案1

您可以使用cat管道:

cat file1 file2 file3 ... fileN | ./script

cat在这种情况下,./script并发运行,数据通过某种 IPC 机制馈送,实际上,该机制是管道或套接字对,具体取决于 shell 和系统。

在 zsh shell 中,您还可以执行以下操作:

./script < file1 < file2 ... < fileN

其工作原理相同。当 stdin(或任何其他文件描述符)多次重定向输入时,zsh 会将其替换为管道的读取端,并cat在内部实现类似的过程,以通过该管道的另一端按顺序提供输入。

./script请注意,如果期望能够在文件中查找,例如当需要在倒带到开头后多次读取它或将其映射到内存中(例如mmap())时,这些方法将不起作用,因为这可以不能使用管道或套接字对来完成。在这种情况下,您需要一个临时的常规的可寻找的) 文件,并且两个命令 (cat./script) 不能同时运行。在 中zsh,通过进程替换的形式可以使这变得更容易,=(cmd)该过程替换扩展为包含 的输出的临时文件的路径,cmd并在之后自动删除:

./script < =(cat file1 file2 file3 ... fileN)

shellfish有类似的东西:

./script < (cat file1 file2 file3 ... fileN | psub -f)

答案2

如果您不想使用管道,可以使用输入重定向和进程替换:

./script < <(cat file1 file2)

答案3

要添加@Jonah Braun 的答案,如果您还需要将进程输出添加到脚本中,即您的文件可能不在磁盘上,但可以通过URL使用curl或类似工具进行访问。

像这样的东西可以用来获取stdout多个进程并通过以下方式在脚本中使用它们stdin

这将是处理输入内容的脚本multi-input.sh

#!/usr/bin/env bash
while read line; do
    echo $line
done

现在测试一下:

$ ./multi-input.sh < <(cat <(echo process 1) <(echo process 2) <(echo process 3))

输出:

process 1
process 2
process 3

<()如果您愿意,可以file使用将进程转换为虚拟进程,因此需要阅读它。它本身不需要它,因为它会做它所做的事情,连接虚拟或真实的文件。fd<cat

相关内容