linux学习笔记3-文本操作(2) sed命令

sed命令

sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。

语法规则

sed即支持在命令行中用单引号输入执行命令,也支持执行含有sed命令的文件。

-e<script>或--expression=<script>:以选项中的指定的script来处理输入的文本文件;
-f<script文件>或--file=<script文件>:以选项中指定的script文件来处理输入的文本文件;
-h或--help:显示帮助;
-V或--version:显示版本信息。</pre>
-n :不显示所有输入内容,只显示经过sed处理的行
-r :sed 的动作支持扩展正则
-i :直接修改读取的文件内容,但不输出

sed 'command(s)' files
sed -f script_files
作用区域

默认情况下,sed命令会作用于文本数据的所有行。如果只想作用于某些行时,则需要使用在命令通过行号或者通过文本过滤的方式前指明作用区域。

单独数字表示某一行,逗号分割指示行范围,例如m,+n表示从m行开始向下n行,m~n表示从m行开始的每n行。
例如' sed -n '2~2 p' test.txt '输出偶数行,' sed -n '1~2 p' test.txt '输出奇数行内容

'/pattern/ command '可以只在包含pattern的行中执行命令。
sed -n '/hello/ p' test.txt ## 只打印包含hello字符串的行。
sed -n '/hello/, /world/ p' test.txt ## 打印两者之间的所有行
sed -n '/hello/,+5 p' test.txt ## 打印第一次出现hello字符串位置处,之后的5行
命令选项释义

sed命令

a\ 在当前行下面插入文本。
i\ 在当前行上面插入文本。
c\ 把选定的行改为新的文本。
d 删除,删除选择的行。
D 删除模板块的第一行。
s 替换指定字符
h 拷贝模板块的内容到内存中的缓冲区。
H 追加模板块的内容到内存中的缓冲区。
g 获得内存缓冲区的内容,并替代当前模板块中的文本。
G 获得内存缓冲区的内容,并追加到当前模板块文本的后面。
l 列表不能打印字符的清单。
n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
N 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。
p 打印模板块的行。

P(大写) 打印模板块的第一行。
q 退出Sed。
b lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。
r file 从file中读行。
t label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
T label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
w file 写并追加模板块到file末尾。
W file 写并追加模板块的第一行到file末尾。
! 表示后面的命令对所有没有被选定的行发生作用。
= 打印当前行号码。
# 把注释扩展到下一个换行符以前。

sed替换标记

g 表示行内全面替换。
p 表示打印行。
w 表示把行写入一个文件。
x 表示互换模板块中的文本和缓冲区中的文本。
y 表示把一个字符翻译为另外的字符(但是不用于正则表达式)
\1 子串匹配标记
& 已匹配字符串标记

sed元字符集
image.png
s 替换

通用写法s/pattern/replacement/[flags]

$ echo book book book book book < test.txt 
book book book book book
$ echo book book book book book >test.txt 
$ sed 's/book/books/' test.txt
books book book book book
$  sed 's/book/books/g' test.txt
books books books books books

pattern支持各种正则表示法,例如

^ ## 行首

$ ## 行尾
. ## 换行符之外的任意单个字符
? ## 匹配之前项0次或者一次

+## 匹配1次或者多次
*## 匹配0次或者多次
{n} ## 匹配n次
{n,} ## 匹配至少n次
{m,n} ## 至少m,最多n
[] ## 匹配任意一个
[-] ## 匹配范围中的一个
[^] ## 排除字符
| ## 或者
# 元字符
\s ## 单个空白
\w ## 单词

p 复制

复制模式空间中的内容,如果不和 -n 参数连用,每一行都会在屏幕输出两次,一行正常输出一行复制,结合 -n
参数后就可以打印需要的内容。

-n选项和p命令一起使用表示只打印那些发生替换的行:
使用后缀 /g 标记会替换每一行中的所有匹配:
当需要从第N处匹配开始替换时,可以使用 /Ng:

$ cat test.txt 
book book book book book
$ sed -n 's/book/books/p' file
sed: can't read file: No such file or directory
t$ sed -n 's/book/books/p' test.txt 
books book book book book
$ sed 's/book/books/g' test.txt
books books books books books

$ echo sksksksksksk | sed 's/sk/SK/3g'
skskSKSKSKSK
$ skskSKSKSKSK
d 删除

支持按照行号或者匹配来删除。

$ grep -v "^#" Homo_sapiens.GRCh37.75.gtf | head -n 10 | cut -f 3-5 > ~/test/test.txt 
$ cd  ~/test
$ cat test.txt 
gene    11869   14412
transcript  11869   14409
exon    11869   12227
exon    12613   12721
exon    13221   14409
transcript  11872   14412
exon    11872   12227
exon    12613   12721
exon    13225   14412
transcript  11874   14409
$ sed '2d' test.txt #删除文件的第2行
gene    11869   14412
exon    11869   12227
exon    12613   12721
exon    13221   14409
transcript  11872   14412
exon    11872   12227
exon    12613   12721
exon    13225   14412
transcript  11874   14409
i\命令 插入(行上)

将 this is a test line 追加到以transcript开头的行前面:

$ sed '/^transcript/i\this is a test line' test.txt 
gene    11869   14412
this is a test line
transcript  11869   14409
exon    11869   12227
exon    12613   12721
exon    13221   14409
this is a test line
transcript  11872   14412
exon    11872   12227
exon    12613   12721
exon    13225   14412
this is a test line
transcript  11874   14409
a\命令 追加(行下)

将 test 追加到 以transcript开头的行后面:

$ sed '/^transcript/a\test' test.txt
gene    11869   14412
transcript  11869   14409
test
exon    11869   12227
exon    12613   12721
exon    13221   14409
transcript  11872   14412
test
exon    11872   12227
exon    12613   12721
exon    13225   14412
transcript  11874   14409
test
/w命令 写入文件

增强版的cp,只复制想要的部分,也可以将一个文件按不同的筛选条件分开保存。
在test.txt 中所有包含exon的行都被写入test2.txt 里:

$ cat test2.txt 
$ cat test.txt 
gene    11869   14412
transcript  11869   14409
exon    11869   12227
exon    12613   12721
exon    13221   14409
transcript  11872   14412
exon    11872   12227
exon    12613   12721
exon    13225   14412
transcript  11874   14409
$ sed -n '/exon/w test2.txt' test.txt
$ cat test2.txt
exon    11869   12227
exon    12613   12721
exon    13221   14409
exon    11872   12227
exon    12613   12721
exon    13225   14412
r命令 从文件读入

file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面:

sed '/exon/r test.txt ' test2.txt

把test.txt读进来去匹配test2.txt文件, 相当于取两者的交集,类似merge。

vip8@VM-0-15-ubuntu:~/test$ sed '/exon/r test.txt '  test2.txt
exon    11869   12227
exon    12613   12721
exon    13221   14409
exon    11872   12227
exon    12613   12721
exon    13225   14412
e 执行外部命令

首先要区别于参数-e,这个e是在''里面的命令

$ sed 'e echo "hello"' test2.txt
hello
exon    11869   12227
hello
exon    12613   12721
hello
exon    13221   14409
hello
exon    11872   12227
hello
exon    12613   12721
hello
exon    13225   14412
e命令 多点编辑

-e选项允许在同一行里执行多条命令

$ sed -e '1,3d' -e 's/exon/hello/' test2.txt
hello   11872   12227
hello   12613   12721
hello   13225   14412

上面sed表达式的第一条命令删除1至3行,第二条命令用hello替换exon。命令的执行顺序对结果有影响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。

n 匹配行下移一行操作

提前读取当前行的下一行内容,并且覆盖当前模式空间中的行

$ seq 5 |sed '3{n;d}'
1
2
3
5

首先匹配到第三行,然后移动到第四行进行删除

$ seq 5 |sed 'n;d' #效果类似与输出奇数行
1
3
5
$ seq 5 |sed -n 'n;p' #效果类似与输出偶数行
2
4

如果hello被匹配,则移动到匹配行的下一行,替换这一行的hello,变为exon,并打印该行,然后继续:

$  sed -e '1,3d' -e 's/exon/hello/' test2.txt
hello   11872   12227
hello   12613   12721
hello   13225   14412
$ sed -e '1,3d' -e 's/exon/hello/' test2.txt > test3.txt
$ sed '/hello/{ n; s/hello/exon/; }' test3.txt
hello   11872   12227
exon    12613   12721
hello   13225   14412
y命令 变形

把1~5行内所有e转变为大写,注意,正则表达式元字符不能使用这个命令:

$ cat test2.txt 
exon    11869   12227
exon    12613   12721
exon    13221   14409
exon    11872   12227
exon    12613   12721
exon    13225   14412
$ sed '1,5y/e/E/' test2.txt
Exon    11869   12227
Exon    12613   12721
Exon    13221   14409
Exon    11872   12227
Exon    12613   12721
exon    13225   14412
$ cat test.txt
gene    11869   14412
transcript  11869   14409
exon    11869   12227
exon    12613   12721
exon    13221   14409
transcript  11872   14412
exon    11872   12227
exon    12613   12721
exon    13225   14412
transcript  11874   14409


###### = 打印行号
$ sed '/transcript/!d;=' test.txt
2
transcript  11869   14409
6
transcript  11872   14412
10
transcript  11874   14409
&已匹配字符串标记

正则表达式 \w+ 匹配每一个单词,使用 [&] 替换它,& 对应于之前所匹配到的单词:

$ echo this is a test line | sed 's/\w\+/[&]/g'
[this] [is] [a] [test] [line]

所有以transcript开头的行都会被替换成它自已加zlyz, 可以加在前后两个位置。

$ sed 's/^transcript/&zlyz/' test.txt 
gene    11869   14412
transcriptzlyz  11869   14409
exon    11869   12227
exon    12613   12721
exon    13221   14409
transcriptzlyz  11872   14412
exon    11872   12227
exon    12613   12721
exon    13225   14412
transcriptzlyz  11874   14409

$ sed 's/^transcript/zlyz&/' test.txt
gene    11869   14412
zlyztranscript  11869   14409
exon    11869   12227
exon    12613   12721
exon    13221   14409
zlyztranscript  11872   14412
exon    11872   12227
exon    12613   12721
exon    13225   14412
zlyztranscript  11874   14409
\1 子串匹配标记

匹配给定样式的其中一部分:

$ echo this is digit 99 in a number | sed 's/digit \([0-100]\)/\1/'
this is digit 99 in a number

trans被标记为1,所有cript会被替换成Ex,并打印出来:

$ cat test.txt 
gene    11869   14412
transcript  11869   14409
exon    11869   12227
exon    12613   12721
exon    13221   14409
transcript  11872   14412
exon    11872   12227
exon    12613   12721
exon    13225   14412
transcript  11874   14409
$ sed -n 's/\(trans\)cript/\1Ex/p' test.txt
transEx 11869   14409
transEx 11872   14412
transEx 11874   14409
vip8@VM-0-15-ubuntu:~/tes
,(逗号)选定行的范围

所有在模板transcript和transcript所确定的范围内的行都被打印:

$ sed -n '/transcript/,/transcript/p' test.txt
transcript  11869   14409
exon    11869   12227
exon    12613   12721
exon    13221   14409
transcript  11872   14412
transcript  11874   14409

打印从第3行开始到第一个包含以transcript开始的行之间的所有行:

$  sed -n '3,/^transcript/p' test.txt 
exon    11869   12227
exon    12613   12721
exon    13221   14409
transcript  11872   14412
sed 单行命令
image.png
image.png

image.png

(图片转自Jimmy老师)
其他操作见http://man.linuxde.net/sed

参考文件:
【1】Jimmy老师Linux基础知识(链接在下面)
【2】linux命令行文本操作一文就够
https://mp.weixin.qq.com/s__biz=MzAxMDkxODM1Ng%3D%3D&idx=1&mid=2247485539&sn=cbb02d48ea5bb90ee5bdf35d501ee428
【3】 生物信息学常见的数据下载,包括基因组,gtf,bed,注释 http://www.biotrainee.com/thread-857-1-1.html
【4】 (13)Hg19基因组的一些分析-生信菜鸟团博客2周年精选文章集 https://cloud.tencent.com/developer/article/1054518
【5】 Linux命令大全

生信技能树公益视频合辑:学习顺序是linux,r,软件安装,geo,小技巧,ngs组学!
B站链接:https://m.bilibili.com/space/338686099
YouTube链接:https://m.youtube.com/channel/UC67sImqK7V8tSWHMG8azIVA/playlists
生信工程师入门最佳指南:https://mp.weixin.qq.com/s/vaX4ttaLIa19MefD86WfUA
学徒培养:https://mp.weixin.qq.com/s/3jw3_PgZXYd7FomxEMxFmw
生信技能树 - 简书 https://www.jianshu.com/u/d645f768d2d5

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

推荐阅读更多精彩内容

  • 1.付出不亚于任何人的努力 2.要谦虚,不要骄傲 3.要每天反省 4.活着,就要感谢 5.积善行,思利他 6.不要...
    linkkof阅读 110评论 0 0
  • 這裡住著 你的死亡 我的死亡 和這個世界應有的冰涼 總是有人談論這個時代 彷彿我們奔跑它就能逐漸光明 其實時代不是...
    白蕙侨阅读 292评论 4 5