Bash 将流输出另存为多个文件
我有一个程序(Bash 将流输出另存为多个文件,bash,shell,command-line,stream,pipe,Bash,Shell,Command Line,Stream,Pipe,我有一个程序(pull)可以下载文件并将其内容(JSON)发送到标准输出,该程序的输入是我要下载的每个文档的id,如下所示: pull one two three > > { ...one } > { ...two } > { ...three } 但是,我现在希望将输出通过管道传输到它发出的每个文件的不同文件中,理想情况下,能够按照最初使用的参数的顺序引用文件名:一两三 所以,我所期待的结果是,如下所示 pull one two three | >
pull
)可以下载文件并将其内容(JSON)发送到标准输出,该程序的输入是我要下载的每个文档的id,如下所示:
pull one two three
>
> { ...one }
> {
...two
}
> { ...three }
但是,我现在希望将输出通过管道传输到它发出的每个文件的不同文件中,理想情况下,能够按照最初使用的参数的顺序引用文件名:一两三
所以,我所期待的结果是,如下所示
pull one two three | > $1.json
>
> saved one.json
> saved two.json
> saved three.json
有什么方法可以达到这个或类似的目的吗
更新
我只想澄清一下程序是如何工作的,以及为什么它可能不是理想的,通过参数循环并对每个声明的参数执行程序多次
每当执行pull
时,它都会执行两个操作:
pull
时提供的参数名称查找项目A+B
,并不理想,因为A
是一个昂贵的操作
因此,我不想让,
abab
我想让abbb
你用艰难的方式来做
for f in one two three; do pull "$f" > "$f.json" & done
除非脚本中的某些内容与多个同时拷贝不兼容,否则这也会使过程更快。如果是,只需将和更改为代码>
更新
试着总是写单独的文件。如果您还需要能够将它们发送到stdout,只需在之后对文件进行cat,或者在编写文件时使用tee
如果这还不行,那么您需要清楚地识别和解析数据块。例如,如果节的开头是唯一一个位置,{
显示为行中的第一个字符,则这是一个合适的sentinel值。使用该值将输出拆分为文件
例如,将其放入另一个脚本:
awk 'NR==FNR { ndx=1; split($0,fn); name=""; next; } /^{/ { name=fn[ndx++]; } { if (length(name)) print $0 > name".json"; }' <( echo "$@" ) <( pull "$@" )
这将执行两个命令并将其输出作为“文件”返回,awk
要处理的输入流。第一个命令只是将一行上提供的参数列表放入数组中,以便awk
加载。第二个命令使用这些参数执行pull
脚本,从而提供您已经获得的流式输出
NR==FNR { ndx=1; split($0,fn); name=""; next; }
这告诉awk
初始化一个文件控制索引,从echo命令(args)中读取单行,并将它们拆分为所需的文件名基数组,然后跳过对该记录的其余处理(它不是“数据”,而是元数据,我们已经完成了处理)我们将name
初始化为一个空字符串,以便检查长度-否则那些前导的空行将以.json
结束,这可能不是您想要的
/^{/ { name=fn[ndx++]; }
这告诉awk
,每当它将{
视为行上的第一个字符时,将输出文件名基设置为当前索引(我们在上面初始化为1),并为下一次增加索引
{ if (length(name)) print $0 > name".json"; }
这告诉awk
将每一行打印到一个名为当前索引指向的文件中,并附加“.json”。if(length(name))
丢弃第一个json块之前的前导空行
结果是,每个新的集合都会从给定的参数中触发一个新的文件名
那对你有用吗
使用中
你做得很辛苦
for f in one two three; do pull "$f" > "$f.json" & done
除非脚本中的某些内容与多个同时拷贝不兼容,否则这也会使过程更快。如果是,只需将&
更改为;
更新
尝试总是写入单个文件。如果您还需要能够将它们发送到stdout,只需在之后对文件进行cat,或者在写入文件时使用tee
如果这不正确,那么您需要清楚地识别和解析数据块。例如,如果节的开头是唯一的位置{
显示为行中的第一个字符,这是一个不错的哨兵值。使用该值将输出拆分为文件
例如,将其放入另一个脚本:
awk 'NR==FNR { ndx=1; split($0,fn); name=""; next; } /^{/ { name=fn[ndx++]; } { if (length(name)) print $0 > name".json"; }' <( echo "$@" ) <( pull "$@" )
这将执行两个命令并将其输出作为“文件”返回,awk
要处理的输入流。第一个命令只是将一行上提供的参数列表放入数组中,以便awk
加载。第二个命令使用这些参数执行pull
脚本,从而提供您已经获得的流式输出
NR==FNR { ndx=1; split($0,fn); name=""; next; }
这告诉awk
初始化一个文件控制索引,从echo命令(args)中读取单行,并将它们拆分为所需的文件名基数组,然后跳过对该记录的其余处理(它不是“数据”,而是元数据,我们已经完成了处理)我们将name
初始化为一个空字符串,以便检查长度-否则那些前导的空行将以.json
结束,这可能不是您想要的
/^{/ { name=fn[ndx++]; }
这告诉awk
,每当它将{
视为行上的第一个字符时,将输出文件名基设置为当前索引(我们在上面初始化为1),并为下一次增加索引
{ if (length(name)) print $0 > name".json"; }
这告诉awk
将每一行打印到一个名为当前索引指向的文件中,并附加“.json”。if(length(name))
丢弃第一个json块之前的前导空行
结果是,每个新的集合都会从给定的参数中触发一个新的文件名
那对你有用吗
使用中
您正在寻找tee
命令吗?在一二三中查找id;如果它只是停留在