前面我们提到pipeline处理多个文件有两种方式,一种是先读取存储数据信息的配置文件,另一种是直接通过一定的条件选取数据。通过find
命令可以帮助我们灵活的查找相关文件,下面具体介绍一下。
Find 表达式
find
的使用格式为:find 路径 表达式
。路径不必多说,可以使用 .
代表当前路径,关键点在于表达式。由于find
命令是递归查看当前目录的,不加其它参数可以用来展示指定目录的文件结构:
$ find data
data
data/seqs
data/seqs/zmaysB_R1.fastq
data/seqs/zmaysB_R2.fastq
data/seqs/zmaysA_R1.fastq
data/seqs/zmaysA_R2.fastq
data/seqs/zmaysC_R1.fastq
data/seqs/zmaysC_R2.fastq
可以指定-maxdepth
来查找深度:
$ find data -maxdepth 1
data
data/seqs
find
表达式本质上是判断,可以通过很多属性来查找文件,例如文件名、文件的创建时间和文件的属性等。其中文件名是最常用的操作,例如我们想要查找目录中zmaysA相关的fastq文件,可以使用如下命令:
$ find data/seqs/ -name "zmaysA*.fastq"
data/seqs/zmaysA_R1.fastq
data/seqs/zmaysA_R2.fastq
可以通过-type f
参数指定结果只返回文件而不是目录:
$ find data/seqs/ -name "zmaysA*.fastq" -type f
data/seqs/zmaysA_R1.fastq
data/seqs/zmaysA_R2.fastq
注:一般来说,-type
我们只会用到f
(文件),d
(目录)和l
(链接)参数值。
多个find
表达式之间可以通过逻辑组合,默认使用-and
,所以上条命令等价于:
$ find data/seqs/ -name "zmaysA*.fastq" -and -type f
data/seqs/zmaysA_R1.fastq
data/seqs/zmaysA_R2.fastq
通过-or
参数查找A与B样本数据:
$ find data/seqs/ -name "zmaysA*.fastq" -or -name "zmaysB*.fastq"
data/seqs/zmaysB_R1.fastq
data/seqs/zmaysB_R2.fastq
data/seqs/zmaysA_R1.fastq
data/seqs/zmaysA_R2.fastq
由于这里只有A,B,C三个样本,上条命令又等价于查找非C样本数据:
$ find data/seqs/ -type f -not -name "zmaysC*.fastq"
data/seqs/zmaysB_R1.fastq
data/seqs/zmaysB_R2.fastq
data/seqs/zmaysA_R1.fastq
data/seqs/zmaysA_R2.fastq
假如此目录下有一个临时文件叫做zmaysB_R1-temp.tastq
,而我们不想分析它,可以再加一条逻辑判断:
$ find data/seqs/ -type f -not -name "zmaysC*.fastq" -not -name "*-temp*"
data/seqs/zmaysB_R1.fastq
data/seqs/zmaysB_R2.fastq
data/seqs/zmaysA_R1.fastq
data/seqs/zmaysA_R2.fastq
find
表达式的完整参数与用法介绍如下表格所示:
对找到的文件执行操作
find
参数-exec
可以对每个匹配的文件执行指定操作,以一个具体例子说明。
首先创建一批临时文件:
$ touch data/seqs/zmays{A,B,C}_R{1,2}-temp.fastq
$ ls data/seqs/
zmaysA_R1.fastq zmaysB_R1.fastq zmaysB_R2-temp.fastq zmaysC_R2-temp.fastq
zmaysA_R1-temp.fastq zmaysB_R1-temp.fastq zmaysC_R1.fastq
zmaysA_R2.fastq zmaysB_R1-temp.tastq zmaysC_R1-temp.fastq
zmaysA_R2-temp.fastq zmaysB_R2.fastq zmaysC_R2.fastq
假如我们想要删除-temp.fastq
结尾的临时文件,可以使用find
命令实现:
$ find data/seqs/ -type f -name "*-temp*" -exec rm -i {} \;
rm: remove regular empty file `data/seqs/zmaysB_R1-temp.tastq'? y
rm: remove regular empty file `data/seqs/zmaysA_R1-temp.fastq'? y
rm: remove regular empty file `data/seqs/zmaysA_R2-temp.fastq'? y
rm: remove regular empty file `data/seqs/zmaysB_R1-temp.fastq'? y
rm: remove regular empty file `data/seqs/zmaysB_R2-temp.fastq'? y
rm: remove regular empty file `data/seqs/zmaysC_R1-temp.fastq'? y
rm: remove regular empty file `data/seqs/zmaysC_R2-temp.fastq'? y
解释:在-exec
参数后面指定想要执行的操作rm
,增加-i
来提供确定选项增加安全性。{}
是占位符,指代find
查找的结果,结尾的\;
是必要的,代表命令结束。
由于这样的删除操作很常用,find
有一个专门的参数-delete
(替代-exec -rm
)。事实上这里的rm
命令可以替换为我们想要执行的任何命令包括常规的生物信息分析,不过find -exec
一般执行较简单的操作,对于复杂的任务,xargs
是一个更好的选择(下节介绍)。