我有一个bash脚本,其中有几个qsubs。他们每个人都在等待一个活跃的qsub在开始之前完成。
我的第一个qsub包括将某个目录中的文件发送到perl程序并将outfiles打印在新目录中。最后,我用所有的工作名称回显数组。这个脚本有意为之。
mkdir -p /perl_files_dir
for ID_FILES in `ls Infiles_dir/*.txt`;
do
JOB_ID=`echo "perl perl_scirpt.pl $ID_FILES" | qsub -j oe `
JOB_ID_ARRAY="${JOB_ID_ARRAY}:$JOB_ID"
done
echo $JOB_ID_ARRAY
我的第二个qsub用于在新的outfile中对我以前使用perl脚本创建的所有文件进行排序,并在使用depend=afterany
完成所有这些作业(大约100个作业)后启动。同样,这部分工作正常。
SORT_JOB=`echo "sort -m -n perl_files_dir/*.txt >>sorted_file.txt" | qsub -j oe -W depend=afterany$JOB_ID_ARRAY`
SORT_ARRAY="${SORT_ARRAY}:$SORT_JOB"
我的问题是,在我的排序文件中,我有一些列要删除(2到6),所以我想到了最后一行使用awk
管道传输到sed
而另一行depend=afterany
SED=`echo "awk '{\$2="";\$3="";\$4="";\$5="";\$6=""; print \$0}' sorted_file.txt \
| sed 's/ //g' >final_file.txt" | qsub -j oe -W depend=afterany$SORT_ARRAY`
最后一步创建final_file.txt
,但将其留空。我在回声之前添加了SED=
因为它会给我Command not found
。
我试过没有管道所以只打印一切。不幸的是它没有打印。 我假设它没有打开我的排序文件,这就是为什么我的sed之后我的最终文件是空的。如果是这样的话,那为什么不会读它?
在我的脚本中,我使用变量来定义我的目录和文件(使用正确的路径)。我知道我的问题不是找到我的文件或目录,因为它们在开始时被完美定义并在整个脚本中使用。我尝试编写整个路径而不是变量,我得到了相同的结果。
答案 0 :(得分:0)
for ID_FILES in `ls Infiles_dir/*.txt`
将此简化为
for ID_FILES in Infiles_dir/*.txt
ls
列出您传递的文件(除非您传递目录,然后列出其内容)。而不是告诉它显示文件列表并解析输出,使用您已有的文件列表!这更可靠(如果文件名包含空格或通配符,解析ls
的输出将失败),更清晰,更快。 Don't parse the output of ls
SORT_JOB=`echo "sort -m -n perl_files_dir/*.txt >>sorted_file.txt" | qsub -j oe -W depend=afterany$JOB_ID_ARRAY`
如果您在正确的地方使用正确的引用形式,那么您的生活将更加简单。不要使用反引号,因为很难知道如何引用内部的东西。 Use $(…)
instead,除了以理智的方式解析之外,它完全等效。
我建议您使用here document作为qsub
提供的shell代码段。您需要担心的引用问题较少,而且更具可读性。
虽然我们处于此状态,但始终在变量替换和命令替换上加上双引号:"$some_variable"
,"$(some_command)"
。令人讨厌的是,shell语法中的$var
并不意味着“获取变量var
的值”,它意味着“获取变量var
的值,将其解析为通配符列表如果有匹配的文件,则用匹配文件列表替换每个模式“。如果替换发生在双引号内(或顺便说一下这里的文档中),则会关闭这些额外的东西:"$var"
表示“获取变量var
的值”。
SORT_JOB=$(qsub -j oe -W depend="afterany$JOB_ID_ARRAY" <<'EOF'
sort -m -n perl_files_dir/*.txt >>sorted_file.txt
EOF
)
我们现在看到报价实际上导致问题的片段。
SED=`echo "awk '{\$2="";\$3="";\$4="";\$5="";\$6=""; print \$0}' sorted_file.txt \ | sed 's/ //g' >final_file.txt" | qsub -j oe -W depend=afterany$SORT_ARRAY`
成为echo
命令参数的字符串是:
awk '{$2=;$3=;$4=;$5=;$6=; print $0}' sorted_file.txt | sed 's/ //g' >final_file.txt
这在语法上是不正确的,这就是为什么你没有得到任何输出。
你没有逃避双重引号里面的awk片段。如果你使用这里的文件,它会更清楚。此外,您不需要SED=
部分。您添加了它是因为您有一个命令替换(…
之间的命令),它替换命令的输出。但是因为你对qsub
命令的输出不感兴趣,所以不要输出它,只需执行它。
qsub -j oe -W depend="afterany$SORT_ARRAY" <<'EOF'
awk '{$2="";$3="";$4="";$5="";$6=""; print $0}' sorted_file.txt |
sed 's/ //g' >final_file.txt
EOF
我不熟悉qsub,但可能有一种方法可以获得错误输出和它运行的命令的返回状态。检查错误输出,你应该看到来自awk的错误。
答案 1 :(得分:-1)
我正在使用的awk
版本,不喜欢角色转义
awk --version
GNU Awk 3.1.7
spuder@cent64$ awk '{\$2="";\$3="";\$4=""; print \$0}' foo.txt
awk: {\$2="";\$3="";\$4=""; print \$0}
awk: ^ backslash not last character on line
尝试以下语法
awk '{for(i=2;i<=7;i++) $i="";print}' foo.txt
作为旁注,如果您使用Torque 4.x,则可能无法使用逗号分隔的作业列表-W depend=
,而您可能需要创建新的PBS声明(-W)为每个工作。
例如......
#Invalid syntax in newer versions of torque
qsub -W depend=foo,bar
<强>资源强>
backslash in gawk fields
Print all but the first three columns
http://docs.adaptivecomputing.com/torque/help.htm#topics/commands/qsub.htm#-W