在武侠小说里,往往有这样一个场景:反面角色从主角手里抢到了某某神器,然后当着主角的面使用它,结果因为内功不够深厚,无法驾驭,被神器反噬,然后主角一般都有露出一种“早就和你说了,你不行”的神情。
Linux里面也有许多比较好用的工具,但是如果你的内力不够深厚,没有一些必要的基本概念的话,那么这些工具可能非但无法让你提高效率,甚至你的结果会更加不可信。本文作为下一篇的铺垫,先介绍一些比较基础的概念。
注:本文用到的数据为拟南芥的注释的gff文件。
本文主要介绍了如下内容,可以选择性的阅读。
- 流
- 重定向
- 管道
- 进程管理
- 退出状态
- 命令替换
流<small>stream</small>
想象一下你面前有一大碗饭,你无法一口咽下去,只能一口一口送进去,然后让慢慢消化。目前生物大数据就是那么一大碗饭,机器的运行内存就是你的消化器官。对于动不动好几十G的测序数据而言,最好的处理的方式,就是以数据流的形式一部分一部分的处理。
大部分的Linux命令都是以流的形式处理数据,例如cat(concatenate files and print on the standard output),就是一行行的读取文件的数据,输出到屏幕上。
# 内容很多,需要一段时间输出
cat TAIR10_GFF3_genes.gff
重定向<small>redirection</small>
当然实际操作上,我们大部分的输出不是到屏幕上,而是到了另一个文件中。比如说把两个文件拼接成一个文件,或者是提取文件的一部分内容,这个时候就需要用到重定向。
直接cat
,数据从标准输入(文件)流出到屏幕上
重定向的符号为>
或>>
,前一个表示覆盖,后一个表示追加:
head -n 10 TAIR10_GFF3_genes.gff > first_ten.gff
tail -n 10 TAIR10_GFF3_genes.gff > last_ten.gff
cat first_ten.gff > new.gff
cat last_ten.gff >> new.gff
上图还提到一个标准错误输出,我们使用2>
和2>>
进行重定向。
例如,我用ls
查看一个不存在的文件
$ ls a.file
ls: cannot access a.file: No such file or directory
如果我不想看到这天信息怎么办,可以直接丢进Linux的“黑洞”设备(/dev/null)中
ls a.file 2> /dev/null
假设你想把first_ten.gff和另一个文件一起合成一个新文件,然后记录那些文件出错,方面之后检查
$cat first_ten.gff wrong.gff > test.gff 2> log.file
$cat log.file
cat: wrong.gff: No such file or directory
其实除了输出可以重定向,输入也可以重定向<
,只不过一般而言我们都是使用文件或者用管道直接提供数据,所以知道存在这个东西就行了。
cat < test.gff > new_test.gff
管道:优美且强大
Unix的一个设计哲学就是整合小程序完成大任务。Linux作为一个类Unix系统,也继承这个思想。管道|
就是负责一种整合多个单任务的小程序来完成复杂的任务.
为什么要使用管道呢?首先,管道使得数据可以不用写到磁盘中,直接在内存中处理。磁盘读写的速度远远低于内存,所以使用管道可以极大地提高计算效率。其次,管道能够让许多小程序像乐高积木一样结合起来,完成一些单个程序无法完成任务,例如统计拟南芥注释信息中各个feature的数量.
$ cat TAIR10_GFF3_genes.gff | cut -f '3' | grep -v 'chromosome' | sort | uniq -c | sort -k1,1nr
215909 exon
197160 CDS
35386 mRNA
35386 protein
34621 five_prime_UTR
30634 three_prime_UTR
28775 gene
3911 mRNA_TE_gene
3903 transposable_element_gene
1274 pseudogenic_exon
926 pseudogenic_transcript
924 pseudogene
689 tRNA
480 ncRNA
180 miRNA
71 snoRNA
15 rRNA
13 snRNA
这里不过多解释这些具体命令的用法,毕竟已经有很多文章介绍过了。
进程管理
每当你敲下一个命令,它就会以一个进程的形式运行。实际上,Linux后台每时每刻都运行着大量的程序,你可以使用ps aux
或top
了解当前正在运行的程序。
当一个程序运行比较快的时候,比如说ls
,cd
等,几乎不会对你当前的终端有任何影响,但是一旦你运行一个比较耗时的命令,例如你要进行序列比对,那么当前的终端就会被这个程序占用。如果不小心按错了,让程序停止,那么估计你的内心是崩溃(别问我为什么会知道)。
所以最好的方法就是让一些耗时的程序运行在后台,方法很简单就是在命令后面加上&
。例如我上面的就比较耗时,我就能放在后台运行。
cat TAIR10_GFF3_genes.gff | cut -f '3' | grep -v 'chromosome' | sort | uniq -c | sort -k1,1nr &
[1] 48450
它会提供一个进程号,用于之后的操作。你可以用fg
查看正在后台运行的命令。
如果你这个时候不想让程序运行,你可以使用fg %cat
将它放到前台,然后使用ctrl+c
结束命令。
或者你突然忘记在一个命令后加&
,而你又发现这个命令耗时比较久,你可以先用ctrl+z
让它暂停到后台,然后用bg
使它在后台运行
bg %cat
[1]+ cat TAIR10_GFF3_genes.gff | cut -f '3' | grep --color=auto -v 'chromosome' | sort | uniq -c | sort -k1,1nr &
退出状态
计算机如何知道你的程序能否工作呢?它们依赖于一种退出状态(exit status)的机制,表示为$?
。
$ echo "$?"
0
所谓正确的结果只有一种(显示为0),而错误的原因却各种各样(1-255)。
退出状态有什么用?主要是在一系列前后关联的程序中,比如说command2运行依赖与command1的成功(&&),而command3却只有在command1失败了(||)才能运行。
true && echo "true"
false || echo "false"
命令替换
所谓的命令替换$()
就是在另一个命令内部中运行并且返回字符串。例如你根据日期来创建文件夹,通常的做法是:看看今天几号,然后mkdir xxx
,但是使用命令替换后就特别的方便了
mkdir $(date +%F)
$ ls
2017-03-24
正则表达式
正则表达式(Regular Expression,RE,regex)是一个强大字符串操作引擎,可用于检索、替换那些符合某个模式(规则)的文本的。
由于我对正则表达式的理解也不够深刻,所以这里就不特别展开,提供如下资料用于自学。
快速入门:https://regexone.com/
你可以在regex101.com和www.debuggex.com校验你写的正则匹配情况。
推荐阅读:《精通正则表达式》
总结
本文简单的介绍了linux中几个比较重要的概念,限于篇幅和个人能力,没有具体展开说明,这里作为抛砖引玉用。