系统内部的Perl字符串调用Java

时间:2015-04-17 16:39:55

标签: java perl weka

我在代码的开头定义了数组@ID。我对这个ID列表做了不同的事情,因此我只在开头定义my $id;(I use strict; warnings)。

也许我简化了太多问题,所以最终还不清楚。

$cv$smo都是$id依赖的,它们都是perl字符串。像这样:

.... 
for $id (@ID) { 

    $cv = $htotal{$id};
    $smo = $hsmote{$id};

    system('java -Djava.util.Arrays.useLegacyMergeSort=true weka.classifiers.meta.FilteredClassifier -t Projects/proteins/$id_MSA/$id_.arff -x $cv -s 0 -p 1,2 -distribution \
        -F "weka.filters.MultiFilter -F \" weka.filters.unsupervised.attribute.Remove -R 7,9\" -F \" weka.filters.unsupervised.attribute.RemoveType -T string\" \
        -F \"weka.filters.supervised.instance.SMOTE -C 0 -K 5 -P $smo -S 1\"" -W weka.classifiers.functions.MultilayerPerceptron -- -L 0.3 -M 0.2 -N 500 -V 0 -S 0 -E 20 -H 0 \
        > Projects/rbfs/$id.rbf');
}
...

为了确保没有Weka错误,我试过,例如cv = 2,smo = 100,id = P12345;它工作正常,所以这是一个插值问题,正如你们有些人提到的那样。

根据您提到的解决方案,我尝试使用双引号+ {}作为@nlu建议:

system('java [...] -t Projects/proteins/"${id}"_MSA/"${id}"_.arff -x "${cv}" -s 0 -p 1,2 -distribution [...]    -F \"weka.filters.supervised.instance.SMOTE -C 0 -K 5 -P "${smo}" -S 1\"" [...] > Projects/rbfs/"${id}".rbf');

但是没有用,我写错了吗?

与此相同(将system()替换为“`)无效:

java [...] -t Projects/150400_GSupdate/proteins/${id}_MSA/${id}.arff -x ${cv} -s 0 -p 1,2 [...] -F \"weka.filters.supervised.instance.SMOTE -C 0 -K 5 -P ${smo} -S [...] > Projects/150400_GSupdate/rbfs/${id}.rbf;

最终对我有用的是字符串连接(正如@Matt建议的那样),但我确信所有其他选项也应该没问题,尽管不知道为什么不这样做。

2 个答案:

答案 0 :(得分:1)

当您在Perl中调用函数时,例如system,您可以使用interpolation替换字符串中的变量。

为了实现这一点,你需要用双引号传递字符串,所以首先你必须用双引号替换周围的单引号。

此外,为了消除字符串中出现的任何变量名称的歧义,你应该这样写:

"${id}" 

避免混淆变量名称,例如ididsomething

此处记录: http://perldoc.perl.org/perldata.html#Scalar-value-constructors

答案 1 :(得分:1)

目前尚不清楚其他变量是否是$ id以外的shell变量?如果你想要替换 $ id,最简单的方法就是使用字符串连接:

for $id (@ID) {
    system('java -Djava.util.Arrays.useLegacyMergeSort=true weka.classifiers.meta.FilteredClassifier -t $PATH/proteins/$id_MSA/$id_.arff -x $cv -s 0 -p 1,2 -distribution \
        -F "weka.filters.MultiFilter -F \" weka.filters.unsupervised.attribute.Remove -R 7,9\" -F \" weka.filters.unsupervised.attribute.RemoveType -T string\" \
        -F \"weka.filters.supervised.instance.SMOTE -C 0 -K 5 -P $smo -S 1\"" -W weka.classifiers.functions.MultilayerPerceptron -- -L 0.3 -M 0.2 -N 500 -V 0 -S 0 -E 20 -H 0 \
        > $PATH/rbfs/' . $id . '.rbf');
}

如果你想要将所有$ something视为perl变量可能是最简单的方法,因为你需要使用"和\"在系统字符串内部是用``运算符替换system(),它基本上与系统做同样的事情。

for $id (@ID) {
    `java -Djava.util.Arrays.useLegacyMergeSort=true weka.classifiers.meta.FilteredClassifier -t $PATH/proteins/$id_MSA/$id_.arff -x $cv -s 0 -p 1,2 -distribution \
        -F "weka.filters.MultiFilter -F \" weka.filters.unsupervised.attribute.Remove -R 7,9\" -F \" weka.filters.unsupervised.attribute.RemoveType -T string\" \
        -F \"weka.filters.supervised.instance.SMOTE -C 0 -K 5 -P $smo -S 1\"" -W weka.classifiers.functions.MultilayerPerceptron -- -L 0.3 -M 0.2 -N 500 -V 0 -S 0 -E 20 -H 0 \
        > $PATH/rbfs/$id.rbf`;
}