最初我运行了shell脚本并将输出定向到一个文件中,然后使用Perl读取文件并解析它。我想将这两个步骤放在一个Perl脚本中。
我试着写这样的东西:
my $in = 'file.txt';
my $read = qx(samtools view -S $in |cut -f 3|sort|uniq -c|awk '{OFS="\t";print \$2,\$1}');
open (IN,"<",$read) || die "cannot open $read: $!";
我收到错误消息,无法打开$ in,并且qx()命令的结果已在屏幕上打印出来。
我无法理解为什么这不起作用以及如何使其发挥作用..
编辑:
来自开放行的错误是:
File name too long
答案 0 :(得分:4)
shell命令生成的字符串可能在末尾包含换行符。通过chomp
chomp $in;
另外,请使用文件句柄的常规变量:
open my $fh, "<", $in or die qq(Can't open "$in": $!);
答案 1 :(得分:3)
您的代码将读取您运行的shell命令的输出,并将该输出(写入STDOUT的任何内容)存储在$in
中。
我怀疑shell命令会在您尝试在其中使用$in
时正确运行,并且可能未定义。
如果您在脚本顶部use strict;
,则可以发现此信息。
my $in = qx(samtools view -S $in |cut -f 3|sort|uniq -c|awk '{OFS="\t";print \$2,\$1}');
// No need to open anything here, just inspect $in
我不熟悉'samtools',但您可能需要修复shell命令并使用正确的内容而不是$in
中的view -S $in
修改强>:
好的,你说你的shell命令会写入一个文件,然后你想要读取它。我误解了!
我上面所说的仍然是正确的,但为了更充分地解决你的问题,你需要做这样的事情:
my $in = 'file.txt';
my $cmd_output = qx(samtools view -S $in |cut -f 3|sort|uniq -c|awk '{OFS="\t";print \$2,\$1}');
open my $fh, '<', $in or die "ERROR: Couldn't open $in for reading: $!";
2ND EDIT ,在评论中回答问题:
为了逐行解析输出,你可以这样做:
foreach my $line (split /\n/, $cmd_output) {
// Do something with $line
}
说实话,你甚至可以在shell上用以下方法更容易地做到这一点:
$ samtools view -S $in |cut -f 3|sort|uniq -c|awk '{OFS="\t";print \$2,\$1}' | perl -lne '... do something with $_ ...'