如何在 shell 块中声明新的 Nextflow 变量?
How to declare a new Nextflow variable in a shell block?
我目前正在编写我的第一个 Nextflow 管道,我尝试在脚本中声明一个新的 Nextflow 变量,但我无法做到。
我想设置一个变量 min_length,其值在文本文件中读取(使用 awk 解析),稍后在我的管道中使用该值作为参数。这是我试过的:
process get_min_len{
input:
file "./foo.tab"
output:
val length_min into min_len_channel
shell:
"""
!{length_min}=`awk '{if ($1=="!{params.bar}") {print $2}}' ./foo.tab`
"""
}
我收到此错误消息:
Error executing process > 'get_min_max_len'
Caused by:
No such variable: length_min
(我也试过像这样初始化 min_length : min_length=0
但它也不起作用。)
有办法吗?
谢谢!
您可以使用 env 限定符来捕获 shell 变量。例如:
params.foo = "foo.tab"
params.bar = "bar"
foo = file( params.foo )
process get_min_len{
input:
path foo
output:
env length_min into min_len_channel
shell:
'''
length_min="$(awk ' == "!{params.bar}" { print }' "!{foo}")"
'''
}
但是,自己定义一个 shell 变量然后捕获它并不能避免创建文件。 env 限定符只是在运行时将一些 syntactic-sugar 添加到您的 shell 脚本中,这样仍然会创建一个输出文件。使用上面的示例,我得到:
$ cat work/d4/37ad3bea12cb64089196744b6558bb/.command.sh
#!/bin/bash -ue
length_min="$(awk ' == "bar" { print }' "foo.tab")"
# capture process environment
set +u
echo length_min=$length_min > .command.env
因此,更好的方法是自己将值写入文件,然后让 Nextflow 从输出通道读取以获取值。您可以为此使用 map 运算符:
process get_min_len{
input:
path foo
output:
path "length_min.txt" into min_len_channel
shell:
'''
awk ' == "!{params.bar}" { print }' "!{foo}" > "length_min.txt"
'''
}
min_len_channel.map { it.text.strip() }.view()
读取文件内容后,您可以调用 strip() 删除字符串开头和结尾的空格(空格、换行符等)。或者,如果您的变量可能需要以额外的空格开始或结束,那么 AWK 'printf' 您的字符串可能会更好,以避免首先使用换行符。
一般来说,除非您正在解析的文件很大,否则我会避免像这样的单独过程。如果你的输入文件只是一些简单的配置文件,你可能会逃避这样的事情:
foo = file( params.foo )
Channel
.from( foo.text )
.splitCsv(sep: '\t')
.filter { col1, col2 -> col1 == params.bar }
.map { col1, col2 -> col2 }
.view()
我目前正在编写我的第一个 Nextflow 管道,我尝试在脚本中声明一个新的 Nextflow 变量,但我无法做到。
我想设置一个变量 min_length,其值在文本文件中读取(使用 awk 解析),稍后在我的管道中使用该值作为参数。这是我试过的:
process get_min_len{
input:
file "./foo.tab"
output:
val length_min into min_len_channel
shell:
"""
!{length_min}=`awk '{if ($1=="!{params.bar}") {print $2}}' ./foo.tab`
"""
}
我收到此错误消息:
Error executing process > 'get_min_max_len'
Caused by:
No such variable: length_min
(我也试过像这样初始化 min_length : min_length=0
但它也不起作用。)
有办法吗? 谢谢!
您可以使用 env 限定符来捕获 shell 变量。例如:
params.foo = "foo.tab"
params.bar = "bar"
foo = file( params.foo )
process get_min_len{
input:
path foo
output:
env length_min into min_len_channel
shell:
'''
length_min="$(awk ' == "!{params.bar}" { print }' "!{foo}")"
'''
}
但是,自己定义一个 shell 变量然后捕获它并不能避免创建文件。 env 限定符只是在运行时将一些 syntactic-sugar 添加到您的 shell 脚本中,这样仍然会创建一个输出文件。使用上面的示例,我得到:
$ cat work/d4/37ad3bea12cb64089196744b6558bb/.command.sh
#!/bin/bash -ue
length_min="$(awk ' == "bar" { print }' "foo.tab")"
# capture process environment
set +u
echo length_min=$length_min > .command.env
因此,更好的方法是自己将值写入文件,然后让 Nextflow 从输出通道读取以获取值。您可以为此使用 map 运算符:
process get_min_len{
input:
path foo
output:
path "length_min.txt" into min_len_channel
shell:
'''
awk ' == "!{params.bar}" { print }' "!{foo}" > "length_min.txt"
'''
}
min_len_channel.map { it.text.strip() }.view()
读取文件内容后,您可以调用 strip() 删除字符串开头和结尾的空格(空格、换行符等)。或者,如果您的变量可能需要以额外的空格开始或结束,那么 AWK 'printf' 您的字符串可能会更好,以避免首先使用换行符。
一般来说,除非您正在解析的文件很大,否则我会避免像这样的单独过程。如果你的输入文件只是一些简单的配置文件,你可能会逃避这样的事情:
foo = file( params.foo )
Channel
.from( foo.text )
.splitCsv(sep: '\t')
.filter { col1, col2 -> col1 == params.bar }
.map { col1, col2 -> col2 }
.view()