Nextflow scripting
Nextflow腳本語言是Groovy編程語言的擴展。Groovy是用于Java虛擬機的強大編程語言。Nextflow語法專門用于以聲明的方式簡化計算管道的編寫。
Nextflow可以執(zhí)行任何Groovy代碼段或使用JVM平臺的任何庫。
詳細了解Groovy編程語言,請參考這些鏈接:
Groovy User Guide
Groovy Cheat sheet
Groovy in Action
下面是關于Nextflow腳本語言中使用的最重要的語言結構的速成課程。
!Warning
Nextflow使用UTF-8作為源文件和應用程序文件的默認文件字符編碼。在使用您最喜歡的文本編輯器編輯Nextflow腳本時,請確保使用UTF-8編碼。
Language basics
Hello world
打印內容就像使用print或println方法一樣簡單。
println "Hello, World!"
兩者之間的唯一區(qū)別是println方法隱式地向打印字符串追加一個 new line character(在輸出結果末尾增加一行)。
Variables(變量)
要定義一個變量,只需給它賦一個值:
x = 1
println xx = new java.util.Date()
println xx = -3.1499392
println xx = false
println xx = "Hi"
println x
Lists(列表)
List對象可以通過將列表項放在方括號中來定義:
myList = [1776, -1, 33, 99, 0, 928734928763]
您可以使用方括號符號訪問列表中的給定項(索引從0開始):
println myList[0]
為了獲得列表的長度,使用size方法:
println myList.size()
了解更多關于列表的信息:
Groovy Lists tutorial
Groovy List SDK
Java List SDK
Maps
Maps用于存儲associative arrays or dictionaries。它們是異構的、命名的數(shù)據(jù)的無序集合:
scores = [ "Brett":100, "Pete":"Did not finish", "Andrew":86.87934 ]
注意,存儲在Map中的每個值可以是不同的類型。Brett是整數(shù),Pete是字符串,Andrew是浮點數(shù)。
可以通過兩種方式訪問Map中的值:
println scores["Pete"]
println scores.Pete
要向Map添加數(shù)據(jù)或修改映射,其語法類似于向列表添加值:
scores["Pete"] = 3
scores["Cedric"] = 120
了解更多關于Map的信息:
Groovy Maps tutorial
Groovy Map SDK
Java Map SDK
多重賦值(Multiple assignment)
數(shù)組或列表對象可以用于一次給多個變量賦值:
(a, b, c) = [10, 20, 'foo']
assert a == 10 && b == 20 && c == 'foo'
賦值操作符左邊的三個變量由列表中相應的項傳入。
更多關于多重賦值(Multiple assignment )的信息,請參閱Groovy文檔。
條件執(zhí)行(Conditional Execution)
任何編程語言最重要的特性之一就是能夠在不同的條件下執(zhí)行不同的代碼。最簡單的方法是使用if構造:
x = Math.random()
if( x < 0.5 ) {
println "You lost."
}
else {
println "You won!"
}
字符串(Strings)
字符串可以用單引號或雙引號('或")來定義:
println "he said 'cheese' once"
println 'he said "cheese!" again'
字符串可以用+連接:
a = "world"
print "hello " + a + "\n"
字符串嵌入值(String interpolation)
單引號字符串和雙引號字符串之間有一個重要的區(qū)別:雙引號字符串支持變量嵌入值,而單引號字符串不支持。
在實踐中,雙引號字符串可以包含任意變量的值(在其名稱前加上$字符前綴),也可以包含任何表達式的值(使用${expression}語法),類似于Bash/shell腳本:
foxtype = 'quick'
foxcolor = ['b', 'r', 'o', 'w', 'n']
println "The $foxtype ${foxcolor.join()} fox"x = 'Hello'
println '$x + $y'
這段代碼打印:
The quick brown fox
$x + $y
多行字符串(Multi-line strings)
跨越多行的文本塊可以通過使用三個單引號或雙引號來定義:
text = """
hello there James
how are you today?
"""
!Note
和之前一樣,雙引號內的多行字符串支持變量嵌入值,而單引號內的多行字符串不支持。
在Bash/shell腳本中,用\字符結束多行字符串中的一行,可以防止用一個新行字符將該行與下一行分隔開:
myLongCmdline = """ blastp \
-in $input_query \
-out $output_file \
-db $blast_database \
-html
"""result = myLongCmdline.execute().text
在前面的例子中,blastp和它的-in、-out、-db和-html參數(shù)實際上是一行。
內置變量(Implicit variables)
腳本內置變量
以下變量是在腳本全局執(zhí)行范圍內內置的:
| Name | Description |
|---|---|
| baseDir | The directory where the main workflow script is located (deprecated in favour of projectDir since 20.04.0). |
| launchDir | The directory where the workflow is run (requires version 20.04.0 or later). |
| moduleDir | The directory where a module script is located for DSL2 modules or the same as projectDir for a non-module script (requires version 20.04.0 or later). |
| nextflow | Dictionary like object representing nextflow runtime information (see Nextflow metadata). |
| params | Dictionary like object holding workflow parameters specifing in the config file or as command line options. |
| projectDir | The directory where the main script is located (requires version 20.04.0 or later). |
| workDir | The directory where tasks temporary files are created. |
| workflow | Dictionary like object representing workflow runtime information (see Runtime metadata). |
配置內置變量(Configuration implicit variables)
在Nextflow配置文件中內置了以下變量::
| Name | Description |
|---|---|
| baseDir | The directory where the main workflow script is located (deprecated in favour of projectDir since 20.04.0). |
| launchDir | The directory where the workflow is run (requires version 20.04.0 or later). |
| projectDir | The directory where the main script is located (requires version 20.04.0 or later). |
流程內置變量(Process implicit variables)
在流程定義范圍內,task內置變量是可用的,它允許訪問當前任務配置指令。例如
process foo {
script:
"""
some_tool --cpus $task.cpus --mem $task.memory
"""
}
在上面的代碼中,task.cpu報告 cpus directive
和task.memorymemory directive
的當前值取決于工作流配置文件中給出的實際設置。
詳情請參閱Process directives。
Closures
簡單地說,closure是可以作為參數(shù)傳遞給函數(shù)的代碼塊。因此,您可以定義一段代碼,然后像傳遞字符串或整數(shù)那樣傳遞它。準確說,您可以創(chuàng)建定義為first class objects的函數(shù)。
square = { it * it }
表達式it * it周圍的花括號告訴腳本解釋器將該表達式視為代碼。it標識符是一個內置變量,表示在調用函數(shù)時傳遞給函數(shù)的值。
一旦編譯,函數(shù)對象將被賦值給變量square,就像前面顯示的其他變量賦值一樣。eg:
println square(9)
and get the value 81.
這并不是很有趣,直到我們發(fā)現(xiàn)可以將函數(shù)square作為參數(shù)傳遞給其他函數(shù)或方法。一些內置函數(shù)接受這樣的函數(shù)作為參數(shù)。列表上的collect方法就是一個例子:
[ 1, 2, 3, 4 ].collect(square)
這個表達式的意思是:創(chuàng)建一個值為1、2、3和4的數(shù)組,然后調用它的collect方法,傳入上面定義的closure 。collect方法遍歷數(shù)組中的每個項,調用該項上的closure,然后將結果放入新數(shù)組中,結果為:
[ 1, 4, 9, 16 ]
要了解更多可以用closure作為參數(shù)調用的方法,請參閱Groovy GDK。
默認情況下,closures 接受一個名為it的參數(shù),但您也可以使用多個自定義命名的參數(shù)創(chuàng)建closures。例如,Map.each()方法可以接受一個帶兩個參數(shù)的closure,它將Map中每個鍵-值對的鍵和關聯(lián)值綁定到這個closure上。這里,我們在closure中使用了明顯的變量名key和value:
printMapClosure = { key, value ->
println "$key = $value"
}[ "Yue" : "Wu", "Mark" : "Williams", "Sudha" : "Kumari" ].each(printMapClosure)
Prints:
Yue=Wu
Mark=Williams
Sudha=Kumari
closure還有另外兩個重要特征。首先,它可以訪問定義它的作用域中的變量,以便與它們進行交互。
其次,closure可以以anonymous的方式定義,這意味著closure沒有指定名稱,而是在需要使用它的地方定義。
作為展示這兩個特性的示例,請參見下面的代碼:
myMap = ["China": 1 , "India" : 2, "USA" : 3]
result = 0
myMap.keySet().each( { result+= myMap[it] } )
println result
在Groovy documentation中了解關于closure的更多信息。
正則表達式(Regular expressions)
正則表達式是文本處理的Swiss Army knife。它們?yōu)槌绦騿T提供了從字符串中匹配和提取patterns的能力。
正則表達式可以通過~/pattern/語法和=~和==~操作符使用。
使用=~來檢查給定的pattern是否出現(xiàn)在字符串中的任意位置:
assert 'foo' =~ /foo/ // return TRUE
assert 'foobar' =~ /foo/ // return TRUE
使用==~檢查字符串是否完全匹配給定的正則表達式pattern。
assert 'foo' ==~ /foo/ // return TRUE
assert 'foobar' ==~ /foo/ // return FALSE
值得注意的是,~操作符從給定的字符串創(chuàng)建Java Pattern對象,而=~操作符創(chuàng)建Java Matcher對象。
x = ~/abc/
println x.class
// prints java.util.regex.Patterny = 'some string' =~ /abc/
println y.class
// prints java.util.regex.Matcher
正則表達式support是從Java導入的。Java的正則表達式語言和API記錄在Pattern Java documentation。
您可能還對這篇文章感興趣:Groovy: Don’t Fear the RegExp。
String replacement
在給定的字符串中替換出現(xiàn)的pattern,請使用replaceFirst和replaceAll方法:
x = "colour".replaceFirst(/ou/, "o")
println x
// prints: colory = "cheesecheese".replaceAll(/cheese/, "nice")
println y
// prints: nicenice
Capturing groups
您可以匹配包含groups的pattern。首先使用=~操作符創(chuàng)建一個匹配器對象。然后,您可以索引 matcher object 來查找matches:matcher[0]返回一個列表,表示字符串中正則表達式的第一個匹配。第一個列表元素是匹配整個正則表達式的字符串,其余元素是匹配每個組的字符串。
下面是它的工作原理:
programVersion = '2.7.3-beta'
m = programVersion =~ /(\d+).(\d+).(\d+)-?(.+)/assert m[0] == ['2.7.3-beta', '2', '7', '3', 'beta']
assert m[0][1] == '2'
assert m[0][2] == '7'
assert m[0][3] == '3'
assert m[0][4] == 'beta'
應用一些syntactic sugar, 您可以在一行代碼中完成相同的工作:
programVersion = '2.7.3-beta'
(full, major, minor, patch, flavor) = (programVersion =~ /(\d+).(\d+).(\d+)-?(.+)/)[0]println full // 2.7.3-beta
println major // 2
println minor // 7
println patch // 3
println flavor // beta
刪除字符串中的一部分(Removing part of a string)
可以使用正則表達式模式刪除部分String值。找到的第一個匹配將被一個空字符串替換:
// define the regexp pattern
wordStartsWithGr = ~/(?i)\s+Gr\w+/// apply and verify the result
('Hello Groovy world!' - wordStartsWithGr) == 'Hello world!'
('Hi Grails users' - wordStartsWithGr) == 'Hi users'
從字符串中刪除第一個是5個字符的單詞:
assert ('Remove first match of 5 letter word' - ~/\b\w{5}\b/) == 'Remove match of 5 letter word'
從字符串中刪除第一個數(shù)字及其末尾的空格:
assert ('Line contains 20 characters' - ~/\d+\s+/) == 'Line contains characters'
Files and I/O
要訪問和處理文件,請使用file方法,該方法返回給定文件路徑字符串的文件系統(tǒng)對象:
myFile = file('some/path/to/my_file.file')
file方法可以引用文件或目錄,具體取決于文件系統(tǒng)中的字符串路徑所引用的內容。
當使用通配符 *, ?, []和{}時,參數(shù)被解釋為一個glob path matcher,file方法返回一個列表對象,其中包含文件名與指定模式匹配的文件的路徑,如果沒有找到匹配,則返回一個空列表:
listOfFiles = file('some/path/*.fa')
!Note
glob模式中的兩個星號(**)類似于*,但可以匹配文件系統(tǒng)路徑中的任意數(shù)量的目錄組件。
默認情況下,通配符不匹配目錄或隱藏文件。例如,如果你想在結果列表中包含隱藏文件,可以添加可選參數(shù)hidden:
listWithHidden = file('some/path/*.fa', hidden: true)
這里是file的可用選項:
| Name | Description |
|---|---|
| glob | When true interprets characters *, ?, [] and {} as glob wildcards, otherwise handles them as normal characters (default: true) |
| type | Type of paths returned, either file, dir or any (default: file) |
| hidden | When true includes hidden files in the resulting paths (default: false) |
| maxDepth | Maximum number of directory levels to visit (default: no limit) |
| followLinks | When true follows symbolic links during directory tree traversal, otherwise treats them as files (default: true) |
| checkIfExists | When true throws an exception of the specified path do not exist in the file system (default: false) |
!Tip
如果你是一個Java geek,您會有興趣知道file方法返回一個 Path對象,它允許你使用在Java程序中常見的方法。
See also: Channel.fromPath.
Basic read/write
給定一個file變量(使用前面示例中所示的file方法聲明),讀取文件就像獲取文件的text屬性的值一樣容易,該屬性以字符串值的形式返回文件內容:
print myFile.text
類似地,您可以通過將字符串值分配給文件的text屬性來將其保存到文件中:
myFile.text = 'Hello world!'
!Note
現(xiàn)有的文件內容被賦值操作覆蓋,它也可以創(chuàng)建不存在的文件。
為了在不刪除現(xiàn)有內容的情況下將字符串值追加到文件中,可以使用append方法:
myFile.append('Add this line\n')
或者使用left shift,這是將文本內容追加到文件的更常用的方法:
myFile << 'Add a line more\n'
二進制數(shù)據(jù)也可以以同樣的方式管理,只是使用文件屬性bytes而不是text。因此,下面的示例讀取文件并以字節(jié)數(shù)組的形式返回其內容:
binaryContent = myFile.bytes
或者,您可以通過寫入操作將字節(jié)數(shù)組數(shù)據(jù)緩沖區(qū)保存到文件中:
myFile.bytes = binaryBuffer
!Warning
上述方法在單個變量或緩沖區(qū)中一次讀取和寫入所有文件內容。因此,在處理大文件時不建議使用它們,因為大文件需要更有效的內存方法,例如逐行讀取文件或使用固定大小的緩沖區(qū)。
Read a file line by line
為了逐行讀取文本文件,你可以使用file對象提供的readLines()方法,它以字符串列表的形式返回文件內容:
myFile = file('some/my_file.txt')
allLines = myFile.readLines()
for( line : allLines ) {
println line
}
常用寫法:
file('some/my_file.txt')
.readLines()
.each { println it }
!Note
readLines()方法會一次讀取所有文件內容,并返回包含所有行的列表。因此,不要使用它來讀取大文件。
要處理大文件,可以使用方法eachLine,它每次只向內存中讀入一行:
count = 0
myFile.eachLine { str ->
println "line ${count++}: $str"
}
高級文件讀取操作(Advanced file reading operations)
Reader類和InputStream類分別為讀取文本和二進制文件提供了很好的方法。
newReader方法為給定的文件創(chuàng)建一個Reader對象,允許您以單個字符、行或字符數(shù)組的形式讀取內容:
myReader = myFile.newReader()
String line
while( line = myReader.readLine() ) {
println line
}
myReader.close()
withReader方法的工作原理與此類似,但當您完成文件處理后,它會自動為您調用close方法。因此,前面的例子可以更簡單地寫成如下:
myFile.withReader {
String line
while( line = it.readLine() ) {
println line
}
}
方法newInputStream和withInputStream的工作方式類似。主要的區(qū)別是它們創(chuàng)建了一個用于寫入二進制數(shù)據(jù)的InputStream對象。
下面是最重要的從文件中讀取的方法:
| Name | Description |
|---|---|
| getText | Returns the file content as a string value |
| getBytes | Returns the file content as byte array |
| readLines | Reads the file line by line and returns the content as a list of strings |
| eachLine | Iterates over the file line by line, applying the specified closure |
| eachByte | Iterates over the file byte by byte, applying the specified closure |
| withReader | Opens a file for reading and lets you access it with a Reader object |
| withInputStream | Opens a file for reading and lets you access it with an InputStream object |
| newReader | Returns a Reader object to read a text file |
| newInputStream | Returns an InputStream object to read a binary file |
閱讀Reader和InputStream類的Java文檔,了解更多關于從文件中讀取數(shù)據(jù)的方法。
高級文件寫入操作(Advanced file writing operations)
Writer和OutputStream類分別為文本和二進制文件的編寫提供了很好的方式,包括對單個字符或字節(jié)的簡單操作,以及對大文件的支持。
例如,給定兩個文件對象sourceFile和targetFile,下面的代碼將第一個文件的內容復制到第二個文件中,用X替換所有U字符:
sourceFile.withReader { source ->
targetFile.withWriter { target ->
String line
while( line=source.readLine() ) {
target << line.replaceAll('U','X')
}
}
}
下面是最重要的寫入文件的方法:
| Name | Description |
|---|---|
| setText | Writes a string value to a file |
| setBytes | Writes a byte array to a file |
| write | Writes a string to a file, replacing any existing content |
| append | Appends a string value to a file without replacing existing content |
| newWriter | Creates a Writer object that allows you to save text data to a file |
| newPrintWriter | Creates a PrintWriter object that allows you to write formatted text to a file |
| newOutputStream | Creates an OutputStream object that allows you to write binary data to a file |
| withWriter | Applies the specified closure to a Writer object, closing it when finished |
| withPrintWriter | Applies the specified closure to a PrintWriter object, closing it when finished |
| withOutputStream | Applies the specified closure to an OutputStream object, closing it when finished |
請閱讀Writer
、PrintWriter
和OutputStream類的Java文檔,了解更多關于將數(shù)據(jù)寫入文件的方法。
列出目錄內容(List directory content)
假設您需要遍歷您選擇的目錄。您可以定義指向它的myDir變量:
myDir = file('any/path')
獲取目錄列表的最簡單方法是使用list或listFiles方法,它們返回目錄的一級元素(文件和目錄)的集合:
allFiles = myDir.list()
for( def file : allFiles ) {
println file
}
!Note
list和listFiles之間的唯一區(qū)別是前者返回一個字符串列表,而后者返回一個允許您訪問文件元數(shù)據(jù)的文件對象列表,例如大小、最后修改時間等。
eachFile方法只允許迭代第一級元素(就像listFiles)。與其他each- methods一樣,each files接受一個closure作為參數(shù):
myDir.eachFile { item ->
if( item.isFile() ) {
println "{item.size()}"
}
else if( item.isDirectory() ) {
println "${item.getName()} - DIR"
}
}
上述方法有幾種變體可用。完整列表見下表。
| Name | Description |
|---|---|
| eachFile | Iterates through first-level elements (files and directories). Read more |
| eachDir | Iterates through first-level directories only. Read more |
| eachFileMatch | Iterates through files and dirs whose names match the given filter. Read more |
| eachDirMatch | Iterates through directories whose names match the given filter. Read more |
| eachFileRecurse | Iterates through directory elements depth-first. Read more |
| eachDirRecurse | Iterates through directories depth-first (regular files are ignored). Read more |
參見:Channel fromPath方法。
創(chuàng)建目錄(Create directories)
給定一個表示不存在目錄的文件變量,如下所示:
myDir = file('any/path')
mkdir方法在給定路徑上創(chuàng)建一個目錄,如果目錄創(chuàng)建成功則返回true,否則返回false:
result = myDir.mkdir()
println result ? "OK" : "Cannot create directory: $myDir"
!Note
如果父目錄不存在,上述方法將失敗并返回false。
mkdirs方法創(chuàng)建以文件對象命名的目錄,包括任何不存在的父目錄:
myDir.mkdirs()
創(chuàng)建鏈接(Create links)
對于一個文件,mklink方法為使用指定的路徑作為參數(shù)的文件創(chuàng)建* file system link *:
myFile = file('/some/path/file.txt')
myFile.mklink('/user/name/link-to-file.txt')
可選參數(shù)表:
| Name | Description |
|---|---|
| hard | When truecreates a hard link, otherwise creates a soft (aka symbolic) link. (default: false) |
| overwrite | When true overwrites any existing file with the same name, otherwise throws a FileAlreadyExistsException (default: false) |
復制文件(Copy files)
copyTo方法將文件復制到新文件或目錄中,或將目錄復制到新目錄中:
myFile.copyTo('new_name.txt')
!Note
如果目標文件已經存在,它將被新的文件替換。還要注意,如果目標是一個目錄,源文件將被復制到該目錄中,并保持文件的原始名稱。
當源文件是一個目錄時,它的所有內容都被復制到目標目錄:
myDir = file('/some/path')
myDir.copyTo('/some/new/path')
If the target path does not exist, it will be created automatically.
!Tip
copyTo方法模仿了Linux命令cp -r <source> <target>,注意:Linux工具通常將以斜杠結尾的路徑(e.g. /some/path/name/)視為目錄,而將不以斜杠結尾的路徑(e.g. /some/path/name)視為常規(guī)文件,Nextflow(由于使用了Java文件API)將這兩個路徑視為相同的文件系統(tǒng)對象。如果路徑存在,它將根據(jù)它的實際類型(即作為一個常規(guī)文件或目錄)進行處理。如果該路徑不存在,則將其視為常規(guī)文件,并自動創(chuàng)建任何缺失的父目錄。
移動文件(Move files)
您可以使用moveTo方法移動文件:
myFile = file('/some/path/file.txt')
myFile.moveTo('/another/path/new_file.txt')
!Note
當與目標同名的文件已經存在時,它將被源文件替換。還要注意,當目標是一個目錄時,文件將被移動到(或移動到)該目錄中,并保持文件的原始名稱。
當源目錄是一個目錄時,所有目錄內容都被移動到目標目錄:
myDir = file('/any/dir_a')
myDir.moveTo('/any/dir_b')
請注意,上述示例的結果取決于目標目錄是否存在。如果目標目錄存在,則將源文件移動到目標目錄,從而產生路徑:
/any/dir_b/dir_a
如果目標目錄不存在,則源文件將被重命名為目標名稱,從而產生路徑:
/any/dir_b
!Tip
moveTo方法模擬了Linux命令mv <source> <target>,與上面給copyTo的警告相同。
重命名文件(Rename files)
您可以使用rename to file方法重命名文件或目錄:
myFile = file('my_file.txt')
myFile.renameTo('new_file_name.txt')
刪除文件(Delete files)
file方法delete刪除給定路徑下的文件或目錄,如果操作成功返回true,否則返回false:
myFile = file('some/file.txt')
result = myFile.delete()
println result ? "OK" : "Can delete: $myFile"
!Note
此方法只刪除不包含任何文件或子目錄的目錄。要刪除一個目錄及其所有內容(即刪除它可能包含的所有文件和子目錄),使用deleteDir方法。
查看文件屬性
以下方法可用于使用file方法創(chuàng)建的文件變量:
| Name | Description |
|---|---|
| getName | Gets the file name e.g. /some/path/file.txt -> file.txt
|
| getBaseName | Gets the file name without its extension e.g. /some/path/file.tar.gz-> file.tar
|
| getSimpleName | Gets the file name without any extension e.g. /some/path/file.tar.gz -> file
|
| getExtension | Gets the file extension e.g. /some/path/file.txt -> txt
|
| getParent | Gets the file parent path e.g. /some/path/file.txt -> /some/path
|
| size | Gets the file size in bytes |
| exists | Returns true if the file exists, or false otherwise |
| isEmpty | Returns true if the file is zero length or does not exist, false otherwise |
| isFile | Returns true if it is a regular file e.g. not a directory |
| isDirectory | Returns true if the file is a directory |
| isHidden | Returns true if the file is hidden |
| lastModified | Returns the file last modified timestamp i.e. a long as Linux epoch time |
例如,下面的行打印文件名和大小:
println "File
{myFile.size()}"
!Tip
任何以get前綴開始的方法名稱的調用都可以省略get前綴和ending()圓括號。因此寫入myFile. getname()和myFile.name是完全相同的,而myFile. getbasename()和myFile.baseName是完全相同的,等等。
獲取和修改文件權限(Get and modify file permissions)
給定一個表示文件(或目錄)的文件變量,getPermissions方法返回一個9個字符的字符串,使用Linux symbolic notation表示文件的權限,例如rw-rw-r--:
permissions = myFile.getPermissions()
類似地,setPermissions方法使用相同的表示法設置文件的權限:
myFile.setPermissions('rwxr-xr-x')
setPermissions方法的第二個版本用三個數(shù)字分別表示所有者、組和其他權限,設置文件的權限:
myFile.setPermissions(7,5,5)
Learn more about File permissions numeric notation.
HTTP/FTP files
Nextflow提供了HTTP/S和FTP協(xié)議的透明集成,將遠程資源作為本地文件系統(tǒng)對象處理。只需將資源URL指定為文件對象的參數(shù):
pdb = file('http://files.rcsb.org/header/5FID.pdb')
然后,您可以像前面幾節(jié)所描述的那樣將其作為本地文件訪問:
println pdb.text
上面的一行代碼打印遠程PDB文件的內容。前面的部分提供了一些代碼示例,展示了如何流式傳輸或復制文件的內容。
!Note
HTTP/S和FTP文件不支持寫入和列表操作。
Counting records
countLines
countLines方法計算文本文件中的行數(shù)。
def sample = file('/data/sample.txt')
println sample.countLines()
以.gz后綴結尾的文件將被GZIP壓縮并自動解壓縮。
countFastq
countFastq方法計算FASTQ格式文件中的records 數(shù)。
def sample = file('/data/sample.fastq')
println sample.countFastq()
以.gz后綴結尾的文件將被GZIP壓縮并自動解壓縮。
REFERENCE
https://www.nextflow.io/docs/latest/script.html#files-and-i-o