添加环境变量

pwd
~/Desktop/opt/bin
vim ~/.bashrc
export PATH=$PATH:~/Desktop/opt/bin
:wq

 Linux基础_LINUX

文本处理

wc -l #统计行数
cut 文本切割
-d 指定分隔符 默认是\t
-f 输出哪几列
cut -f 1 #输出切割后的第一列
cut -f 1,3-8,15 #输出切割后的第1列,第3-8列,第15列

 Linux基础_LINUX_02

less -S xxx.txt | cut -d 'h' -f 1

 Linux基础_LINUX_03

cat hg38.tss|awk '{print $2}' |sort |uniq -c 
6050 chr1
2824 chr10
2 chr10_GL383545v1_alt
#去掉后面的碎片基因
cat hg38.tss|awk '{print $2}' | sort | uniq -c | grep -v '_'
6050 chr1
2824 chr10
2 chr10

正则表达式regular expression:

 Linux基础_LINUX_04

()与[]的差别:()为多选,[]为单选, 对比下就知道

cat SRR519926_1.fastq | egrep 'TA(A+)TA' --color=always | head
@ 匹配了多种模式

 Linux基础_LINUX_05

cat SRR519926_1.fastq | egrep 'TA[A+]TA' --color=always | head
@ 仅匹配了一种模式

 Linux基础_LINUX_06

(e)grep:号称“Almost~最快文本搜索”

​​--color=always/auto: 始终/自动高亮显示搜索字段

搜索特定信息

grep "AT1G01680" *.gff | head -n5

 Linux基础_LINUX_07

排除特定信息

grep "AT1G01680" *.gff | grep -v "protein" | head -n5

 Linux基础_LINUX_08

查找某段序列并输出上下文

grep -A n显示后面n行; -B n显示前面n行
grep -A 2 "CAAATTGAATTAAG" *.fas

 Linux基础_LINUX_09

查找特定序列并计算出现了几次

grep -c "CAAATTGAATTAAG" *.fas 
或者: grep "CAAATTGAATTAAG" *.fas | wc -l
@ 如果单纯输出 就用grep -o

精准匹配某个基因

@ 搭配正则表达式
@ 比如要匹配开头为AT1G250,结尾为3的基因名
grep "AT1G250.*3$" *.gff
=> 得到了两条AT1G25053 & AT1G25083

 Linux基础_LINUX_10

并非完美~

虽然grep很强大,但是他也并非十全十美,
他的一个不足之处就在于,对于存在换行符的字符串,它会搜不到。
例如我们想找TAIR10_chr_all.fas 中95-100之内的‘CCACT’ 碱基
tail -n100 TAIR10_chr_all.fas | head -n5 | egrep 'CCACT'
搜索显示无结果

tail -n100 TAIR10_chr_all.fas | head -n5 | tr -d '\n' | egrep 'CCACT'
tr -d(delete) 是删除特定字段
稍加改变下之后便可以搜索到结果

sed:

流编辑器~就像水流一样,按行从数据读取--执行命令--显示结果,一气呵成
整个过程在一个位于内存中叫Pattern Space模式空间中进行,
因此不会改变原始文件内容

使用方法:

sed [options] 'Adress Command1;Command2;...' file...
[options]包括:
-n: 只显示经过sed处理的行,保存在模式空间的未处理行不显示【常用】
-i:直接修改读取内容,不输出【慎用,他会修改源文件】
-r:使用拓展正则表达式
n,m+ 表示从n向下m行;n~m表示从n开始的每m行
比如我要输出偶数行:
sed -n “2~2 p" Thanos.txt
比如要打印包含bio的行:
sed -n '/bio/p' Thanos.txt
比如打印包含bio与包含planet之间的所有行:
sed -n '/bio/, /planet/p' Thanos.txt
还可以与行号连用:打印包含bio行以及下面6行
sed -n '/bio/, +6 p'Thanos.txt
p:复制模式空间的内容,一般与-n连用【否则会一次输出两次】
d:删除【按行号或匹配条件】
删除第5行后面所有的行
sed '5,$d'
例如,要在文件开头插入一行,三列name、length、feature
sed '1i name\tlength\tfeature' Thanos.txt
例如,要在末尾追加内容【表示最后一行】 
sed 'a bioinfoplanet' Thanos.txt
!:反向执行
sed '/bio/!d' Thanos.txt 效果等于
sed -n '/bio/p' Thanos.txt
=:打印行号
sed '/bio/!d;=' Thanos.txt
s:替换【支持正则】
s/pattern/replace/flags

一种特殊情况,还比较常用,就是如果替换/怎么办?
方法一:使用转义符\/
方法二 :用@ | ! ^ 替换
例如:要更改当前目录中的部分内容
pwd | sed 's@/home/tmp/bio@/home/tmp/bioinfo@'
实用的sed单行命令:
@ 删除空行
sed '/^$/d'
@ 每一行下增加一行空行
sed G
@ 每三行增加一行空白行
sed '0~3G'
@ 在匹配的pattern后面加入一行空白行
sed '/pattern/G'
@ cat的功能实现
sed ''
@ head的功能实现
sed '3 q' =》输出前三行
@ tee功能实现
sed -n 'p; w newfile'
@ grep功能实现
sed -n '/pattern/p'
@ grep -v功能实现
sed -n '/pattern/p!'
@ 计算行数
sed -n '$='
@ 多个内容同时替换(例如将1、2、3替换成4)
sed 's/1\|2\|3/4/'
@ 显示包含“haha”、“xixi”、“yeah”的行
sed '/haha/d!; /xixi/d!; /yeah/d!'

awk:号称“Almost~最强文本操作”

工作职责:主打行【如果一个文本文档是一张表格,
每一行代表一个记录,每一列代表域,awk就是处理记录专用】

工作流程: 先逐行读取并记录,将行信息整合入$0 =>
指定分隔符(默认空格),分割成各个列$1,$2,$3...

再执行awk 'pattern1 {command1}; pattern2 {command2}...'
模拟cat打印行
awk '{print $0}' Thanos.txt | head -n3
选择列打印
@ 利用.gff文件练习 ~属于情况一
awk '{print $1,$3,$4,$5}' *.gff | head -n5
【当然,这里默认是空格分割,如果想tab分割呢?】
awk '{[print $1 "\t" $3 "\t" $4 "\t" $5 "\t"]}'

 Linux基础_LINUX_11

列重排
@ 这个功能相当于下面cut的升级版 属于情况一
@ 可以改变列的顺序,并且可以自定义分隔符
awk '{print $4","$5":"$1":"$3}' *.gff | head -n5

 Linux基础_LINUX_12

转换格式
比如将gff/gtf格式转为bed格式
【注意两点:一、转换后的bed格式分隔符为tab;
二、bed与gff的坐标格式不同:0-坐标系统有BAM、BED、BCFv2、PSL;1-坐标系统有SAM、VCF、GFF、wiggle。需要做出调整】
cat test.gtf | awk '{print $1 "\t" $4-1 "\t" $5}' > test.bed
如果单有这些简单的功能,还算不上Almost最强,加上下面这些你再试试?
逻辑运算(<, > , <=, >=, ==, !=
数学运算(+- * / %
关系运算(与&& || 非!)
正则运算 (实则就是将你想匹配的东西放在/ /里,
然后在它前面加~匹配, !~ 不匹配)
@ 我想匹配在3号染色体上,长度大于1.5k的注释,看前五行    
@ ~情况二,我们只需要pattern就好
awk '$5-$4 > 15000 && $1 ~/Chr3/' *.gff | head -n5

 Linux基础_LINUX_13

```平均值
我想看一下3号染色体上编码区(CDS)的平均值 ~情况二
awk 'BEGIN {len=0;line=0};$1 ~/Chr3/ && $3 ~/CDS/ { len += ( $5 - $4 );line += 1}; END {print "CDS_mean=" len/line}' *.gff
=>
CDS_mean=225.019

特殊的变量:

NR代表当前所在行号,想要打印3-4行内容:head -4|tail -2
就等同于awk 'NR>=3 && NR<=4 {print $0}'`

NF表示目前的记录被分割的字段的数目,即Number of Field
例如要输出文件的列数【默认空格分割,这里设为tab分割】:
awk -F \t” '{print NF; exit}' test.bed

OFS 指定列输出分隔符
例如要输出文件的列数【默认空格分割,这里设为tab分割】:
awk -F \t” '{print NF; exit}' test.bed

常用的还有:

cut:提取

-f 提取指定字段(filed)
cut -f 1,3,4,5 GFF3_genes.gff | head
cut -f 1-5
-d: 指定分隔符(默认\t)

-c 截取一定范围的字符,例如cut -c1-3就是截取三个字符
例如,将bed文件第一列的染色体编号去掉
awk '{print 1}' *.bed | cut -c4
反之,要再添加上的话:
awk '{print1}' *.bed | cut -c4 | awk '{print "chr"$1}'

uniq: 去重

与sort连用,-c 在每列旁边显示该行重复出现的次数
-d 只输出重复的行

column:格式化输出

一般cut后的结果参差不齐,可以用它对齐输出结果,默认\t
指定分隔符:以逗号为例, -t -s ','

sort: 排序

-k 被排序的部位,包含start 和stop两部分, 二者,隔开;每次使用都要加上这两部分【默认排序第一列】
-n 按数字大小排序
sort -k1,1 -k2,2n my.bed 对第一列首字母按字符排序,对第二列按数值
-r 降序(默认升序)【与-k连用表示对某一列逆序】
-t 指定字块分隔符(默认tab)
-c 检查是否按照某种方式排过顺序【echo $? 返回0表示执行成功】
-V 排序时不用ASCII码方式排列,就显示为正常的排序方式
【比如三个染色体编号chr1, chr2, chr11。不加-V排序结果就是chr1-- chr11 -- chr2; 加了-V就是:chr1 -- chr2 -- chr11】
【一般数据处理过程中不用这个操作,原始的格式处理更快】

join:连接

要求两个文件之间必须有共同点,所以使用join前必须先将文件排序
格式:join -1 <file1_field> -2 <file2_field> <file1> <file2>
共同点通过-1 -2传递进来,比如说两个文件的某一列有共同点
例如一个bed文件前三列如下:my.bed
chr1 34 36
chr2 38 40
chr1 25 39
chr3 12 18
一个染色体长度文件为:length.txt
chr1 54362
chr2 35613
chr3 46612

join这两个文件之前先sort
sort -k1,1 my.bed > sorted.bed
sort -c -k1,1 length.txt
以双方第一列为共同点拼接:
join -1 1 -2 1 sorted.bed length.txt > with_length.txt
【假如两个文件没有共同点,比如length.txt少了chr2数据,那么join后的文件也缺少chr2数据】

举个🌰【很大的那种!】:

@0 拿到手数据,可以先ll -h *.gff 看一下文件大小
less -SN *.gff 看一下文本内容
@1 去除多余的#注释行 与 空行, 打印行号
grep -v "#" *.gff | grep -v "^$" | wc -l
=> 590264行(一般这种使用量大的数据是没有多余行的,但是人类的有。这里只是为了演示用法)
@2 截取gff文件的1-5列,将第二列除去, 输出默认的前10行到test.txt中
cut -f 1,3,4,5 *.gff > test.txt
cat test.txt | head
=>
Chr1 chromosome 1 30427671
Chr1 gene 3631 5899
Chr1 mRNA 3631 5899
Chr1 protein 3760 5630
Chr1 exon 3631 3913
Chr1 five_prime_UTR 3631 3759
Chr1 CDS 3760 3913
Chr1 exon 3996 4276
Chr1 CDS 3996 4276
Chr1 exon 4486 4605
接下来对截取的test.txt进行处理
@3 想根据第二列的feature进行排序【注意sort -k的使用!】
sort -k 2,2 test.txt | head -n5
=>
Chr1 CDS 3760 3913
Chr1 CDS 3996 4276
Chr1 chromosome 1 30427671
Chr1 exon 3631 3913
Chr1 exon 3996 4276

@4 【进阶】先根据第一列Chr数字大小降序排序,再根据第二列排序
你是不是试过了这个》sort -k 1,1nr -k 2,2 *.txt | head -n5
你会发现输出的结果第一列还是Chr1开头,并没有降序,为什么呢?
=》原因就是,-k 1,1还是根据第一个字段的全部排序,还是根据Chr1的‘C’进行匹配,其实我们只想用第一个字段的数字(也就是第一个字段的第四个字符)进行匹配
=》如何实现?其实sort -k参数 内置了这个功能。使用-k 1.4,1.4 就是根据这种特定方式匹配啦
sort -k 1.4,1.4nr -k 2,2 *.txt | head -n5
=>
Chr5 CDS 10001590 10001736
Chr5 CDS 10004720 10004824
Chr5 CDS 10004720 10004824
Chr5 CDS 10005070 10005255
Chr5 CDS 10005070 10005255
有没有很好用?!
如果只是想统计一下整体的feature(第三列)情况,可以这样:
cut -f 3 *.gff |sort|uniq -c >feature.txt
=>
197160 CDS
7 chromosome
215909 exon
34621 five_prime_UTR
28775 gene
35386 mRNA
3911 mRNA_TE_gene
180 miRNA
想看哪个feature最多?没问题,一步搞定!
sort -k 1r feature.txt
=>
215909 exon
197160 CDS
35386 protein
35386 mRNA
34621 five_prime_UTR
30634 three_prime_UTR

 Linux基础_LINUX_14

 Linux基础_LINUX_15