首页 > 解决方案 > 使用perl系统函数自动重复执行matlab脚本

问题描述

matlab 脚本“NPBSS_CLR.m”可以在这里找到https://github.com/NWPU-903PR/NPBSS_MATLAB。它一次只能处理一个输入文件,并且需要以下输入格式:

>> NPBSS_CLR('file.fsa', '-n 1') 

我有数千个文件要处理,并希望自动处理。首先,我准备在终端中使用 matlab。

cd /Applications/MATLAB_R2018a.app/bin 
./matlab -nodesktop -nosplash 

然后我尝试运行我为这项工作编写的 Perl 脚本,但出现“意外标记 `'file.fsa'' 附近的语法错误”错误。这种类型的错误之前已经讨论过很多,但似乎每种情况都相当独特,我无法在我自己的代码中纠正这个问题。这可能是因为我试图在 Matlab 中使用 Perl 的方式。如果是这种情况,我怎样才能让 Matlab 为我自动处理每个文件?我像这样运行 perl 脚本:

>> perl('Automate_NPBSS.pl')

剧本:

#!/usr/bin/perl
use strict; 
use warnings;
use File::Basename;

my @files = glob ('/Users/user/Desktop/NPBSS_MATLAB-master/*');
foreach my $file (@files){
    my $short_name = basename($file);
    if ($file =~ m/([TAGC]{20})(_\d+\.fsa)/){
        system(" NPBSS_CLR('$short_name', '-n 1') ");
    }
}

具体错误示例:

sh: -c: line 0: syntax error near unexpected token `'TTCCACTGCGGAGCACCAGT_91.fsa','
sh: -c: line 0: `NPBSS_CLR('TTCCACTGCGGAGCACCAGT_91.fsa', '-n 1') '

标签: matlabperlcommand-lineautomation

解决方案


它看起来像这一行:

system(" NPBSS_CLR('$short_name', '-n 1') ")

最终会调用这样的东西作为 shell 命令:

NPBSS_CLR('TTCCACTGCGGAGCACCAGT_91.fsa', '-n 1')

这里有两个问题:

  • NPBSS_CLR 是一个 Matlab 函数,而不是您可以从 shell 调用的操作系统可见命令
  • 括号 ( (...)) 对 shell 有特殊意义

要从 Perl 运行 Matlab 函数system(...),您需要让它启动 Matlab 以使用matlab'-r选项运行该函数。像这样的东西:

system("/Applications/MATLAB_R2018a.app/bin/matlab -nodesktop -nosplash -r \"NPBSS_CLR('$short_name', '-n 1'); exit\"");

.../matlab调用将使您运行 Matlab,而转义的引号 ( \"...\") 将“保护”括号。

但如果我是你,我会通过完全删除 Perl 脚本并将其重写为可以NPBSS_CLR直接调用该函数的 Matlab M 代码脚本来简化此设置。这样您就不必担心引用您的值来通过 Perl 和 shell,避免启动多个 Matlab 会话的开销,并且可以在单个 Matlab 会话的调试器中处理所有内容。像这样的东西:

%Automate_NPBSS.m
function Automate_NPBSS

cd('/Users/user/Desktop/NPBSS_MATLAB-master/');
d = dir('*.fsa');
for i = 1:numel(d)
    file = d(i);
    if isempty(regexp(file.name, '[TAGC]{20}_\d+\.fsa'))
        continue
    end
    NPBSS_CLR(file.name, '-n 1');
end
end

(唯一需要注意的是,如果没有 Matlab 并行计算工具箱,您将无法轻松实现并行化,因此如果您想这样做,您需要坚持使用system()Perl 或 Matlab。)


推荐阅读