sed与awk的学习(一)
最近利用busco做细菌基因组组装评估,得到了很多文本文件形式的评估结果,想从多个文本文件中提取自己想要的内容,发现sed和awk可以完成上述工作,因此有了学习的动力,找了一本书 sed&awk。

TIM图片20181025101230.png
了解基本操作
以下是sed&awk书上的范例
sed基本操作
- 创建sed&awk文件夹
czh@ubuntu:~$ mkdir sed&awk
#进入该文件夹
czh@ubuntu:~$ cd /home/czh/Desktop/sed&awk
#创建一个list文件
czh@ubuntu:~/Desktop/sed&awk$ touch list
czh@ubuntu:~/Desktop/sed&awk$ ls
list
- 编辑list文件,将书上的示例内容粘贴进去
czh@ubuntu:~/Desktop/sed&awk$ vim list
czh@ubuntu:~/Desktop/sed&awk$ cat list
John Daggett, 341 King Road, Plymouth MA
Alice Ford, 22 East Broadway, Richmond VA
Orville Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Lans Road, Beaver Falls PA
Eric Adams, 20 Post Road, Sudbury MA
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Bayshore Pkwy, Mountain View CA
Sal Carpenter, 73 6th Street, Boston MA
- 将list文本中的MA替换成Massachusetts,替换命令为s
czh@ubuntu:~/Desktop/sed&awk$ sed 's/MA/Massachusetts/' list
John Daggett, 341 King Road, Plymouth Massachusetts
Alice Ford, 22 East Broadway, Richmond VA
Orville Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Lans Road, Beaver Falls PA
Eric Adams, 20 Post Road, Sudbury Massachusetts
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Bayshore Pkwy, Mountain View CA
Sal Carpenter, 73 6th Street, Boston Massachusetts
- 将’ MA’替换成’, Massachusetts’ ,注意MA前面是有空格的,必须用‘’将其包围起来。
czh@ubuntu:~/Desktop/sed&awk$ sed 's/ MA/, Massachusetts/' list
John Daggett, 341 King Road, Plymouth, Massachusetts
Alice Ford, 22 East Broadway, Richmond VA
Orville Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Lans Road, Beaver Falls PA
Eric Adams, 20 Post Road, Sudbury, Massachusetts
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Bayshore Pkwy, Mountain View CA
Sal Carpenter, 73 6th Street, Boston, Massachusetts
- 1 多重指令的使用,使用分号分隔命令,同时将’ MA’和’ PA’分别替换成’, Massachusetts’ 和 ’ Pennsylvania’.
czh@ubuntu:~/Desktop/sed&awk$ sed 's/ MA/, Massachusetts/;s/ PA/, Pennsylvania/' list
John Daggett, 341 King Road, Plymouth, Massachusetts
Alice Ford, 22 East Broadway, Richmond VA
Orville Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Lans Road, Beaver Falls, Pennsylvania
Eric Adams, 20 Post Road, Sudbury, Massachusetts
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Bayshore Pkwy, Mountain View CA
Sal Carpenter, 73 6th Street, Boston, Massachusetts
5.2 在每个指令前放置-e。
czh@ubuntu:~/Desktop/sed&awk$ sed -e 's/ MA/, Massachusetts/' -e 's/ PA/, Pennsylvania/' list
John Daggett, 341 King Road, Plymouth, Massachusetts
Alice Ford, 22 East Broadway, Richmond VA
Orville Thomas, 11345 Oak Bridge Road, Tulsa OK
Terry Kalkas, 402 Lans Road, Beaver Falls, Pennsylvania
Eric Adams, 20 Post Road, Sudbury, Massachusetts
Hubert Sims, 328A Brook Road, Roanoke VA
Amy Wilde, 334 Bayshore Pkwy, Mountain View CA
Sal Carpenter, 73 6th Street, Boston, Massachusetts
- 脚本文件
在命令行上输入较长的编辑脚本是不实际的。这就需要创建包含编辑指令的脚本文件来解决这个问题。使用-f选项来指定命令行上的脚本文件的名字,格式如下:
sed -f scriptfile file
将想要执行的所以编辑命令都放置在文件中。我们按照惯例创建临时脚本文件sedscr。
czh@ubuntu:~/Desktop/sed&awk$ touch sedscr
czh@ubuntu:~/Desktop/sed&awk$ vim sedscr
czh@ubuntu:~/Desktop/sed&awk$ cat sedscr
s/ MA/, Massachusetts/
s/ PA/, Pennsylvania/
s/ CA/, California/
s/ VA/, Virginia/
s/ OK/, Oklahoma/
下面的命令将读取sedscr中的所以替换命令, 并将这些命令应用于输入文件list的每一行。
czh@ubuntu:~/Desktop/sed&awk$ sed -f sedscr list
John Daggett, 341 King Road, Plymouth, Massachusetts
Alice Ford, 22 East Broadway, Richmond, Virginia
Orville Thomas, 11345 Oak Bridge Road, Tulsa, Oklahoma
Terry Kalkas, 402 Lans Road, Beaver Falls, Pennsylvania
Eric Adams, 20 Post Road, Sudbury, Massachusetts
Hubert Sims, 328A Brook Road, Roanoke, Virginia
Amy Wilde, 334 Bayshore Pkwy, Mountain View, California
Sal Carpenter, 73 6th Street, Boston, Massachusetts
值得注意的是,显示在屏幕上的结果是临时的,输入文件的内容不会被改变。
- 保存输入结果
只要将sed的输出重定向到另一个程序中,才能捕获文件中的输出。
czh@ubuntu:~/Desktop/sed&awk$ sed -f sedscr list > newlist
czh@ubuntu:~/Desktop/sed&awk$ ls
list newlist sedscr
czh@ubuntu:~/Desktop/sed&awk$ cat newlist
John Daggett, 341 King Road, Plymouth, Massachusetts
Alice Ford, 22 East Broadway, Richmond, Virginia
Orville Thomas, 11345 Oak Bridge Road, Tulsa, Oklahoma
Terry Kalkas, 402 Lans Road, Beaver Falls, Pennsylvania
Eric Adams, 20 Post Road, Sudbury, Massachusetts
Hubert Sims, 328A Brook Road, Roanoke, Virginia
Amy Wilde, 334 Bayshore Pkwy, Mountain View, California
Sal Carpenter, 73 6th Street, Boston, Massachusetts
- 阻止输入行的自动显示
sed的默认操作是输出每个输出行。-n选项可以阻止自动输出。当指定给选项时,每个要生成输出的指令都必须包含打印命令p。
czh@ubuntu:~/Desktop/sed&awk$ sed -n -e 's/MA/Massachusetts/p' list
John Daggett, 341 King Road, Plymouth Massachusetts
Eric Adams, 20 Post Road, Sudbury Massachusetts
Sal Carpenter, 73 6th Street, Boston Massachusetts
这里只会显示被命令改变的行。
选项总结
| 选项 | 描述 |
|---|---|
| -e | 编辑随后的指令 |
| -f | 跟随脚本的文件名 |
| -n | 阻止输入行的自动输出 |
awk基本操作
- awk的运行语法:
awk ‘instructions’ files - 用脚本文件调用awk的语法:
awk -f script files - 操作实例
3.1 打印输入文件中的每行的第一个字段。
czh@ubuntu:~/Desktop/sed&awk$ awk '{ print $1 }' list
John
Alice
Orville
Terry
Eric
Hubert
Amy
Sal
$1表示每个输入行的第一个字段的值。此处没有指定模式,因此打印语句应用于所以行。
3.2 指定模式下打印输入文件中的内容
3.2.1 指定打印出含有MA的行。
czh@ubuntu:~/Desktop/sed&awk$ awk '/MA/' list
John Daggett, 341 King Road, Plymouth MA
Eric Adams, 20 Post Road, Sudbury MA
Sal Carpenter, 73 6th Street, Boston MA
如此看来,awk更像一种查询语言,从文本中提取有用的信息。
3.2.2 指定打印出含有MA的行的第一个字段。
czh@ubuntu:~/Desktop/sed&awk$ awk '/MA/ { print $1 }' list
John
Eric
Sal
- 将字段分隔号改为逗号。
默认情况下,awk使用空格或制表符作为字段分隔符将输入的分隔成字段。
使用-F选项将字段分隔符改成逗号。
czh@ubuntu:~/Desktop/sed&awk$ awk -F, '/MA/ { print $1 }' list
John Daggett
Eric Adams
Sal Carpenter
将每个字段单独打印在一行上
czh@ubuntu:~/Desktop/sed&awk$ awk -F, '{ print $1; print $2; print $3}' list
John Daggett
341 King Road
Plymouth MA
Alice Ford
22 East Broadway
Richmond VA
Orville Thomas
11345 Oak Bridge Road
Tulsa OK
Terry Kalkas
402 Lans Road
Beaver Falls PA
Eric Adams
20 Post Road
Sudbury MA
Hubert Sims
328A Brook Road
Roanoke VA
Amy Wilde
334 Bayshore Pkwy
Mountain View CA
Sal Carpenter
73 6th Street
Boston MA
选项总结
| 选项 | 描述 |
|---|---|
| -f | 跟随脚本的文本名 |
| -F | 改变字段分隔符 |
| -v | 跟随var=value |
同时使用sed和awk
在UNIX中,管道可用于将一个程序的输出作为输入传递给另一个程序。
- 现在综合使用sed和awk来产生报表作为示例。
#创建一个名为nameState的脚本文件
czh@ubuntu:~/Desktop/sed&awk$ touch nameState
czh@ubuntu:~/Desktop/sed&awk$ vim nameState
czh@ubuntu:~/Desktop/sed&awk$ cat nameState
s/ CA/, California/
s/ MA/, Massachusetts/
s/ OK/, Oklahoma/
s/ PA/, Pennsylvania/
s/ VA/, Virginia/
由nameState产生的输出被传递到一个awk的程序中,这个awk程序用于从每条记录中提取州的名字。
czh@ubuntu:~/Desktop/sed&awk$ sed -f nameState list | awk -F, '{ print $4 }'
Massachusetts
Virginia
Oklahoma
Pennsylvania
Massachusetts
Virginia
California
Massachusetts