nextflow中文文檔(3):Nextflow腳本(Nextflow scripting)

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

打印內容就像使用printprintln方法一樣簡單。

println "Hello, World!"

兩者之間的唯一區(qū)別是println方法隱式地向打印字符串追加一個 new line character(在輸出結果末尾增加一行)。

Variables(變量)

要定義一個變量,只需給它賦一個值:

x = 1
println x

x = new java.util.Date()
println x

x = -3.1499392
println x

x = false
println x

x = "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中使用了明顯的變量名keyvalue

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.Pattern

y = '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,請使用replaceFirstreplaceAll方法:

x = "colour".replaceFirst(/ou/, "o")
println x
// prints: color

y = "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
}
}

方法newInputStreamwithInputStream的工作方式類似。主要的區(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

閱讀ReaderInputStream類的Java文檔,了解更多關于從文件中讀取數(shù)據(jù)的方法。

高級文件寫入操作(Advanced file writing operations)

WriterOutputStream類分別為文本和二進制文件的編寫提供了很好的方式,包括對單個字符或字節(jié)的簡單操作,以及對大文件的支持。

例如,給定兩個文件對象sourceFiletargetFile,下面的代碼將第一個文件的內容復制到第二個文件中,用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')

獲取目錄列表的最簡單方法是使用listlistFiles方法,它們返回目錄的一級元素(文件和目錄)的集合:

allFiles = myDir.list()
for( def file : allFiles ) {
println file
}

!Note

listlistFiles之間的唯一區(qū)別是前者返回一個字符串列表,而后者返回一個允許您訪問文件元數(shù)據(jù)的文件對象列表,例如大小、最后修改時間等。

eachFile方法只允許迭代第一級元素(就像listFiles)。與其他each- methods一樣,each files接受一個closure作為參數(shù):

myDir.eachFile { item ->
if( item.isFile() ) {
println "{item.getName()} - size:{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.getName() size:{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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容