【问题标题】:Without re-writing Python/Perl scripts, how would I pipe outputs together in a bash script?如果不重新编写 Python/Perl 脚本,我将如何在 bash 脚本中将输出连接在一起?
【发布时间】:2017-06-16 14:02:35
【问题描述】:

我有以下 Perl 脚本(尽管这适用于 Python 和其他脚本语言):script1.plscript2.plscript3.pl

这些脚本的编写方式,用户使用输入标志执行它们,输出是保存的文件。

perl script1.pl --i input1.tsv   ## this outputs the file `outputs1`
perl script2.pl --i outputs1     ## this outputs the file `outputs2`
perl script3.pl --i outputs2     ## this outputs the file `final_output`

(对于 Python 爱好者,这是python script1.py

现在,我想创建一个可执行的 bash 脚本,它允许用户简单地使用 input1 并获得输出作为返回 final_output

这就是我只用一个 perl 脚本execute.sh 来做到这一点的方法:

#!/bin/sh

source ~/.bash_profile

FLAG1="--i=$1"

perl script1.pl $FLAG1

可以在命令行上运行execute.sh input1.tsv

对于我的三个脚本示例,我如何将中间输出通过管道传输到中间脚本以创建一个 execute.sh 脚本,例如outputs1 变成script2.pl,然后outputs2 变成scripts3.pl,等等?

有没有办法让我在不重写 perl/python 脚本的情况下做到这一点?

编辑:附加信息:问题是我实际上不知道输出是什么。文件名根据原始的 inputs1.tsv 更改。现在,我确实知道输出的文件扩展名。但是输出 1 和输出 2 具有相同的文件扩展名。

【问题讨论】:

  • 通过使用正确的文件名调用脚本,与手动执行相同,除了它在脚本中。不需要魔法。
  • 脚本是否需要特定的输入/输出文件?通常,您只需将它们以< input1.tsv perl script1.pl | perl script2.pl | perl script3.pl > outputs2 的形式通过管道传输(当然,还要编写脚本,这样就可以了)
  • 如果脚本总是输出到硬连线的文件名,除了改变脚本别无他法。
  • 您能否解释一下为什么在 bash 脚本中连续运行三个命令不起作用?
  • @ShanZhengYang 这将是问题中的好信息。

标签: python linux bash perl shell


【解决方案1】:

此类情况的最佳实践是让脚本从标准输入读取并写入标准输出。在这种情况下,很容易将它们连接在一起,如下所示:

perl script1.pl < input1.tsv | perl script2.pl | perl script3.pl

在您的情况下,您可以编写如下脚本:

#!/bin/sh
perl script1.pl --i input1.tsv
perl script2.pl --i outputs1 
perl script3.pl --i outputs2

这并不理想,但它会做你想做的事。它将读取 input1.tsv,并写入 output3。

【讨论】:

  • “在你的情况下,你可以写一个这样的脚本”见上面的 cmets。问题是我实际上不知道输出是什么。文件名根据原始的 inputs1.tsv 更改。现在,我确实知道输出的文件扩展名。但是输出 1 和输出 2 具有相同的文件扩展名。
  • perl script1.pl &lt; input1.tsv | perl script2.pl | perl script3.pl 我可能遗漏了一些东西。该脚本由perl script.pl --i input 工作。 ``perl script1.pl perl script1.pl 的输出通过perl script2.pl 正确读取?
  • 我的意思是,如果您有机会自己从头开始编写它,我建议您编写它以便它从标准输入读取并写入标准输出——那么您就不会对文件名有任何限制。如果您不知道并且无法预测各种脚本的输出文件的名称,则很难实现自动化。您可以执行以下操作,例如捕获目录中所有文件的名称、运行脚本、再次捕获名称,然后查看发生了什么变化。这有点荒谬,但听起来你可能没有很多更好的选择......
【解决方案2】:

您的问题不是这样说的,但假设您可以使用--o 标志指定输出文件:

perl script1.pl --i input1.tsv --o /dev/stdout | perl script2.pl --i /dev/stdin --o /dev/stdout | perl script3.pl --i /dev/stdin --o final_output

/dev/stdin/dev/stdout 是神奇的 unix 文件,它们分别写入进程的 stdinstdout

【讨论】:

  • 不幸的是,我必须写一个--o 标志
  • 是的,如果脚本只是硬编码为某个文件名,那么你就完蛋了!
猜你喜欢
  • 2015-10-30
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 2017-11-21
  • 2021-12-13
  • 2012-11-19
  • 2013-12-25
  • 2010-10-22
相关资源
最近更新 更多