sed

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

2019-01-13  本文已影响5人  土豆学生信

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

上一篇下一篇

猜你喜欢

热点阅读