Java系统调用中的Perl字符串
我在代码的开头定义了array@ID。我用这个id列表做不同的事情,因此我定义了Java系统调用中的Perl字符串,java,perl,weka,Java,Perl,Weka,我在代码的开头定义了array@ID。我用这个id列表做不同的事情,因此我定义了my$id仅在开头(I使用严格;警告) 也许我把问题简化得太多了,所以最后不清楚了 $cv和$smo都是依赖于$id的,它们都是perl字符串。像这样: .... for $id (@ID) { $cv = $htotal{$id}; $smo = $hsmote{$id}; system('java -Djava.util.Arrays.useLegacyMergeSort=true
my$id代码>仅在开头(I使用严格;警告
)
也许我把问题简化得太多了,所以最后不清楚了
$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}-s0-p1,2[…]-F\'weka.filters.supervised.instance.SMOTE-c0-k5-p${smo}-s[…]>Projects/150400_GSupdate/rbfs/${id}.rbf
最后对我起作用的是字符串连接(正如@Matt所建议的),但我确信所有其他选项也应该可以,尽管我不知道为什么不可以。在Perl中调用函数时,如system
在您的例子中,您可以使用插值来替换字符串中的变量
要实现这一点,您需要以双引号传递字符串,因此首先必须用双引号替换周围的单引号
此外,为了消除字符串中出现的任何变量名称的歧义,您应该这样编写它们:
"${id}"
避免混淆变量名,如id
和idsomething
此处记录:
不清楚其他变量是否是$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变量,那么在系统字符串中使用“and\”最简单的方法可能是将system()替换为``运算符,这基本上与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`;
}
另外,for循环应该使用一个局部变量,以便对我的$id(@id){}
。这表明您没有在脚本顶部使用strict;use warnings;,这将帮助您避免常见问题。或者您正在从范围外重新使用$id,这不是一个好计划,除非您有充分的理由,而这看起来不像是一个好计划。