系统调用中的 Perl 字符串 Java
Perl strings inside system call to Java
我在代码开头定义了数组@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 所建议的),但我确信所有其他选项也应该没问题,尽管不知道为什么。
当您在 Perl 中调用函数时,例如您的 system
,您可以使用 interpolation
来替换字符串中的变量。
您需要在双引号中传递字符串才能发生这种情况,因此首先您必须用双引号替换周围的单引号。
此外,为了消除字符串中出现的任何变量名的歧义,您应该这样写:
"${id}"
以避免混淆变量名称,例如 id
和 idsomething
。
记录于此:
http://perldoc.perl.org/perldata.html#Scalar-value-constructors
不清楚其他变量是否是shell除$id以外的变量?如果你想 just $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`;
}
我在代码开头定义了数组@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 所建议的),但我确信所有其他选项也应该没问题,尽管不知道为什么。
当您在 Perl 中调用函数时,例如您的 system
,您可以使用 interpolation
来替换字符串中的变量。
您需要在双引号中传递字符串才能发生这种情况,因此首先您必须用双引号替换周围的单引号。
此外,为了消除字符串中出现的任何变量名的歧义,您应该这样写:
"${id}"
以避免混淆变量名称,例如 id
和 idsomething
。
记录于此: http://perldoc.perl.org/perldata.html#Scalar-value-constructors
不清楚其他变量是否是shell除$id以外的变量?如果你想 just $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`;
}