【shell笔记>文本处理|专项】Linux数据文本处理工具(2)

1

file 查看文件编码

wsx@wsx-ubuntu:~$ file regular_express.txt 
regular_express.txt: ASCII text, with CRLF, LF line terminators

常用的大型数据文件一般存为ASCII码形式(像几大基因bank的数据文件),而我们自己认为创建的常为UTF-8,所以有时候认为处理文件需要会碰到把UTF-8编码的字符插入到ASCII码文件里去了。遇到这种问题,我们可以用hexdump -c命令查看出错的地方(手边没有这样的文件,就不举例了)。

sort对文本排序

我们先创建一个bed格式文件来试试这个命令:

wsx@wsx-ubuntu:~$ cat test.bed 
chr1    26  39
chr3    32  47
chr1    40  50
chr1    9   28
chr2    35  54
chr1    10  19
wsx@wsx-ubuntu:~$ sort test.bed 
chr1    10  19
chr1    26  39
chr1    40  50
chr1    9   28
chr2    35  54
chr3    32  47

可以明显看到文本按照第一列进行了排序。
默认,sort用空格或tab键作为域(列)分隔符。如果我们用其他形式的分隔符,需要用-t选项指定。

下面是对bed文件最通用的排序命令:

wsx@wsx-ubuntu:~$ sort -k1,1 -k2,2n test.bed 
chr1    9   28
chr1    10  19
chr1    26  39
chr1    40  50
chr2    35  54
chr3    32  47

基本操作bedtools软件都会先用这个命令对bedtools文件排序。
现在略加解释一下,sort-k选项指定某列的排序方式。而每次使用-k选项都要带上指定列的范围(start, end)。如果只指定一列,就为(start,start)了,像上面命令的-k1,1就是。也许你会觉得-k2,2n很奇怪,这里的n指定程序把第二列当做数值对待。如果不做设定,都是当做字符对待(shell都是这么对待数值数据的)。所以总结其他这一行命令就是对第一列按照字符排序,第二列按照数值排序。

我们可以用-c选项检查一个文件是不是已经按照过某种方式排过序了。

wsx@wsx-ubuntu:~$ sort -k1,1 -k2,2n test.bed | sort -k1,1 -k2,2 -c
sort:-:2:无序: chr1   10  19
wsx@wsx-ubuntu:~$ echo $?
1
wsx@wsx-ubuntu:~$ sort -k1,1 -k2,2n test.bed | sort -k1,1 -k2,2n -c
wsx@wsx-ubuntu:~$ echo $?
0

上面可以清楚地看到sort是怎么对待文件的(一般shell返回0表示成功执行)。

wsx@wsx-ubuntu:~$ tsfds
tsfds:未找到命令
wsx@wsx-ubuntu:~$ echo $?
127
wsx@wsx-ubuntu:~$ echo test
test
wsx@wsx-ubuntu:~$ echo $?
0

shell的命令退出状态码表示了该命令执行的完成的某种情况。不同的状态码有不同的含义,具体可以百度查阅(我之前整理的shell笔记应该讲过,可以看看)。

反向排序用-r选项。如果你只想反转一列,可以把它加在-k选项后。

wsx@wsx-ubuntu:~$ sort -k1,1 -k2,2nr test.bed 
chr1    40  50
chr1    26  39
chr1    10  19
chr1    9   28
chr2    35  54
chr3    32  47

现在我给test.bed加一行:

wsx@wsx-ubuntu:~$ cat test.bed 
chr1    26  39
chr3    32  47
chr1    40  50
chr1    9   28
chr2    35  54
chr1    10  19
chr11   22  56

你会发现有点奇怪

wsx@wsx-ubuntu:~$ sort -k1,1 -k2,2n test.bed 
chr1    9   28
chr1    10  19
chr1    26  39
chr1    40  50
chr11   22  56
chr2    35  54
chr3    32  47

怎么chr11chr2前面?其实sort排序的方式有点像查字典。例子中,命令先比较c,然后比较h,然后比较r,接着比较1,自然11会在2前面了。这里可以添加V选项修改。

wsx@wsx-ubuntu:~$ sort -k1,1V -k2,2n test.bed 
chr1    9   28
chr1    10  19
chr1    26  39
chr1    40  50
chr2    35  54
chr3    32  47
chr11   22  56

是不是觉得这样更可观一些?不过通常在处理数据时不做此处理,符合 规范的数据可以让后续处理程序效率更高。

基本掌握sort这些也够用了,它主要为后续处理服务。如果想知道其他的用法,查查吧,同时欢迎发文来交流。

uniq寻找唯一值

首先创建样例文本

wsx@wsx-ubuntu:~$ cat test.letter 
A
A
B
C
B
C
C
C
D
F
D

使用uniq看看

wsx@wsx-ubuntu:~$ uniq test.letter 
A
B
C
B
C
D
F
D

尼玛,怎么不对。它好像只去掉了连续的同一字符。怎么办?想想我们刚学了什么命令?sort不是刚好可以把同样的字符弄到一起去吗,然后再使用uniq,嘿嘿:

wsx@wsx-ubuntu:~$ sort test.letter | uniq
A
B
C
D
F

哟呵,got you。

-c选项计数:

wsx@wsx-ubuntu:~$ sort test.letter | uniq -c
      2 A
      2 B
      4 C
      2 D
      1 F

把结果再排序

wsx@wsx-ubuntu:~$ sort test.letter | uniq -c | sort -rn
      4 C
      2 D
      2 B
      2 A
      1 F

-d选项只输出重复行

wsx@wsx-ubuntu:~$ cat test.letter 
A
A
B
C
B
C
C
C
D
F
D
wsx@wsx-ubuntu:~$ uniq -d test.letter 
A
C
wsx@wsx-ubuntu:~$ sort test.letter | uniq -d
A
B
C
D

使用时需要注意处理不同导致的结果差异。

Join 命令
用来连接文件。
假设现在我们有两个文件:

wsx@wsx-ubuntu:/tmp$ cat example.bed 
chr1    26  39
chr1    32  47
chr3    11  28
chr1    40  49
chr3    16  27
chr1    9   28
chr2    35  53
wsx@wsx-ubuntu:/tmp$ cat example_length.txt 
chr1    53453
chr2    34356
chr3    24356

我想把第二个文件说明染色体长度添加到第一个文件对应染色体的第三列。
我们首先要给文件排序(使用join前必须做),然后使用join命令。

wsx@wsx-ubuntu:/tmp$ sort -k1,1 example.bed > example_sorted.bed
wsx@wsx-ubuntu:/tmp$ sort -c -k1,1 example_length.txt 
wsx@wsx-ubuntu:/tmp$ cat example_sorted.bed 
chr1    26  39
chr1    32  47
chr1    40  49
chr1    9   28
chr2    35  53
chr3    11  28
chr3    16  27
wsx@wsx-ubuntu:/tmp$ join -1 1 -2 1 example_sorted.bed  example_length.txt > example_with_length.txt
wsx@wsx-ubuntu:/tmp$ cat example_with_length.txt 
chr1 26 39 53453
chr1 32 47 53453
chr1 40 49 53453
chr1 9 28 53453
chr2 35 53 34356
chr3 11 28 24356
chr3 16 27 24356

命令基本语法是

join -1 <file_1_field> -2 <file_2_field> <file_1> <file_2>

既然名字叫join,就是两者必须有共同之处,通过共同的支点将两者连为一体。
-1-2选项后接参数分别指定了这个支点,也就是连接的域(列)。比如例子中,都是两个文件的第一列。

两个文件中,第一列都共有chr1(2)(3)。 如果不一致会出现什么情况呢?

wsx@wsx-ubuntu:/tmp$ join -1 1 -2 1 example_sorted.bed  example_length_alt.txt chr1 26 39 53453
chr1 32 47 53453
chr1 40 49 53453
chr1 9 28 53453
chr2 35 53 34356

如果第二个文件没有chr3join之后也没了!!

我们可以通过-a选项指定哪一个文件可以不遵循配对

wsx@wsx-ubuntu:/tmp$ join -1 1 -2 1 -a 1 example_sorted.bed  example_length_alt.txt 
chr1 26 39 53453
chr1 32 47 53453
chr1 40 49 53453
chr1 9 28 53453
chr2 35 53 34356
chr3 11 28
chr3 16 27

awk
awk是文本处理的一把好手,虽然它不能像pythonR干一些高级复杂的主题工作,但是它具备完整的命令操作和编程体系。

awk是一门语言,我不可能在学习的时候能够逻辑清晰详细地介绍给大家。主要是还通过实例来了解用法,加深认识。手册可以参考http://man.linuxde.net/awk

首先要明白的是,awk按行处理数据。在shell知识里,如果把一个文档看做一张表。那么一行就是一个记录,一列就是一个。可以看出,awk就是按记录处理文本的。

其次是awk的程序结构是

pattern {action}

pattern可以是表达式或者正则表达式。pattern有点像if语句,当它满足时就会执行相应的动作。

另一个awk核心是它用$0表示所有列,$1$2...等等表示对应的列。我们可以很方便地用它进行操作。

wsx@wsx-ubuntu:/tmp$ awk '{print $0}' example.bed 
chr1    26  39
chr1    32  47
chr3    11  28
chr1    40  49
chr3    16  27
chr1    9   28
chr2    35  53
wsx@wsx-ubuntu:/tmp$ awk '{print $1}' example.bed 
chr1
chr1
chr3
chr1
chr3
chr1
chr2
wsx@wsx-ubuntu:/tmp$ awk '{print $2}' example.bed 
26
32
11
40
16
9

print语句就像动作一样输出你操作的结果。

wsx@wsx-ubuntu:/tmp$ awk '{ print $2 "\t" $3}' example.bed 
26  39
32  47
11  28
40  49
16  27
9   28
35  53
wsx@wsx-ubuntu:/tmp$ awk '{ print $2  $3}' example.bed 
2639
3247
1128
4049
1627
928
3553
wsx@wsx-ubuntu:/tmp$ awk '{ print $2 , $3}' example.bed 
26 39
32 47
11 28
40 49
16 27
9 28
35 53

了解上述几个语句的不同。

表示染色体名一般用带chr或者不带chr标志两种方式。当我们要用到这两种时,肯定要让它们能够对应起来,也就是转换。awk命令可以非常方便地添加chr标记。

下面我先把例子文件的chr去掉,然后加上试试。

wsx@wsx-ubuntu:/tmp$ awk '{ print $1}' example.bed
chr1
chr1
chr3
chr1
chr3
chr1
chr2
wsx@wsx-ubuntu:/tmp$ awk '{ print $1}' example.bed | cut -c4 
1
1
3
1
3
1
2
wsx@wsx-ubuntu:/tmp$ awk '{ print $1}' example.bed | cut -c4 | awk '{print "chr"$1}'
chr1
chr1
chr3
chr1
chr3
chr1
chr2

awk作为一门编程语言,它支持各种操作符(运算,逻辑,判断)喔。

wsx@wsx-ubuntu:/tmp$ awk '$3 - $2 >18' example.bed 
chr1    9   28
wsx@wsx-ubuntu:/tmp$ awk '$1 ~/chr1/ && $3 - $2 > 10' example.bed 
chr1    26  39
chr1    32  47
chr1    9   28

# 这里 ~ 符号用来匹配正则表达式

还有awk存在一些变量,像NR表示行号,OFS表示输出分隔符等。

wsx@wsx-ubuntu:/tmp$ awk 'NR >= 3 && NR <= 5' example.bed 
chr3    11  28
chr1    40  49
chr3    16  27

如果我们想把gtf文件转换成为bed格式,可以使用

wsx@wsx-ubuntu:~/Work/research/Promoter_Research$ head -n1000 Homo_sapiens.GRCh37.75.gtf | awk '!/^#/{ print $1 "\t" $4-1 "\t" $5} ' | head -n 3
1   11868   14412
1   11868   14409
1   11868   12227

因为篇幅有限,我不可能输出所有结果,所以只取部分数据做了运算。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容

  • linux资料总章2.1 1.0写的不好抱歉 但是2.0已经改了很多 但是错误还是无法避免 以后资料会慢慢更新 大...
    数据革命阅读 12,151评论 2 33
  • 转载 原文的排版和内容都更加友好,并且详细,我只是在这里贴出了一部分留作自己以后参考和学习,如希望更详细了解AWK...
    XKirk阅读 3,200评论 2 25
  • 基础命令 主要的命令和快捷键 Linux系统命令由三部分组成:cmd + [options]+[operation...
    485b1aca799e阅读 1,092评论 0 0
  • awk介绍awk变量printf命令:实现格式化输出操作符awk patternawk actionawk数组aw...
    哈喽别样阅读 1,562评论 0 4
  • 知识点 sort uniq cut wc sed命令 awk命令 crontab定时器 sort sort 命令对...