第十八章:初识sed和gawk

文本处理

sed编辑器

sed编辑器可以基于输入到命令行的或是存储在命令文本文件中的命令来处理数据流中的数据。

它每次读取一行,用提供的编辑器命令匹配数据、按命令中指定的方式修改流中的数据,然后将生成的数据输出到STDOUT。在流编辑器将所有命令与一行数据进行匹配后,它会读取下一行数据并重复这个过程。在流编辑器处理完流中的所有数据行后,它就会终止。
sed命令格式:

sed options script file

sed命令选项

选项 描述
-e script 在处理输入时,将script中指定的命令添加到运行的命令中
-f file  在处理输入时,将file中指定的命令添加到运行的命令中
-n 不要为每个命令生成输出,等待print命令来输出

在命令行定义编辑器命令

默认情况下,sed会编辑器会将指定的命令应用到STDIN输入流上。

  1. $ echo "This is a test" | sed 's/a/not a/'
  2. This is not a test

在命令行使用多个编辑器命令

使用-e即可。

注意:多个命令都写在同一对引号之间,并用分号隔开。并且在命令末尾和分号之间不能有空格。

  1. $ echo "This is a test" | sed -e 's/a/not a/;s/This/That/'
  2. That is not a test

从文件中读取编辑器命令

  1. $ cat sed_script
  2. s/brown/white/
  3. s/fox/elephant/

使用-f选项即可。

  1. $ echo "The quick brown fox jumps over the lazy dog." | sed -f sed_script
  2. The quick white elephant jumps over the lazy dog.

文件中的sed命令可以使用换行或分号隔开

gawk程序

在gawk编程语言中,可以做下面的事:

1.定义变量来保存数据

2.使用算数和字符串操作符来处理数据

3.使用结构化编程概念,比如if-then语句和循环

4.提取数据文件中的数据元素并将他们按另一顺序或格式重新放置。

gawk命令格式:

gawk option program file

gawk选项

选项 描述
-F fs 指定行中分隔数据字段的字段分隔符
-f file 指定读取程序的文件名
-v var=value 定义gawk程序中的一个变量以及默认值
-mf N 指定要处理的数据文件中的最大字段数
-mr N 指定数据文件中的最大数据行数
-W keyword 指定gawk的兼容模式或警告等级

从命令行读取程序脚本

gawk程序用一对花括号来定义。

由于gawk命令行假定脚本是单个文本字符串,所以必须将脚本放到单引号中。

  1. $ gawk '{print "Hello"}'

键入回车之后,并不会马上执行,等待你输入文本。gawk会对这行文本运行一遍所有的程序脚本

和sed一样,gawk程序会针对数据流中的每行文本执行一遍程序脚本。

使用数据字段变量

gawk会将如下变量分配给它在文本行中发现的每个数据字段:

$0表示整个文本行;$1表示文本行中第一个数据字段,依此类推

gawk中默认的字段分隔符是任意空白字符

  1. $ echo "A B C
  2. > D E F" | gawk '{print $1}'
  3. A
  4. D

使用-F选项指定分隔符

  1. $ gawk -F : '{print $1}' /etc/passwd
  2. root
  3. daemon
  4. bin
  5. sys
  6. ……

在程序脚本中使用多个命令

同sed,多个命令使用分号隔开即可。

  1. $ echo "I'm a person." | gawk '{$3="man.";print $0}'
  2. I'm a man.

这里先将$3赋值,然后打印这句话。打印得结果是已经替换了$3之后的结果了。

从文件中读取程序

  1. $ cat gawk_test
  2. {
  3. text="'s home directory is "
  4. print $1 text $6
  5. }

同样可以使用多个命令,可以用换行或分号分割命令

  1. $ gawk -F: -f gawk_test /etc/passwd
  2. root's home directory is /root
  3. daemon's home directory is /usr/sbin
  4. ……

gawk在引用变量得时候,并不像shell那样,需要使用美元符

在处理数据前运行脚本

BEGIN关键字会在处理数据前,执行指定的脚本

  1. $ gawk 'BEGIN { print "hello world"}'
  2. hello world

在处理数据后运行脚本

当然是使用END关键字了

  1. $ cat gawk_test
  2. BEGIN {
  3. print "Before read the file"
  4. FS=":"
  5. }
  6.  
  7. {
  8. print $1
  9. }
  10.  
  11. END {
  12. print "The End"
  13. }

注意:使用FS设置分割符

  1. $ gawk -f gawk_test /etc/passwd
  2. Before read the file
  3. root
  4. daemon
  5. ……
  6. sshd
  7. Debian-exim
  8. The End

sed编辑器基础

更多的替换选项

替换标记

默认情况下,对匹配到的内容只会替换一次

  1. $ echo "That is a test." | sed 's/ //'
  2. Thatis a test.

如果想改变这种方式,需要使用替换标记

s/pattern/replacement/flags

有4种替换标记:

数字,表明将替换第几处模式匹配的地方

  1. $ echo "That is a test." | sed 's/ //2'
  2. That isa test.
  3. $ echo "That is a test." | sed 's/ //6'
  4. That is a test.

g,替换所有匹配到的文本

  1. $ echo "That is a test." | sed 's/ //g'
  2. Thatisatest.

p,表明原来行的地方要打印出来。通常与-n选项一起使用

上面已经说过,-n选项表示不输出,等待print命令来输出。

  1. $ echo "That is a test." | sed -n 's/ //p'
  2. Thatis a test.

w file,将替换的结果写到文件中

  1. $ echo "That is a test." | sed -n 's/ //w out'
  2. $ cat out
  3. Thatis a test.

替换字符

如果我们想要替换文本中出现的文件路径,那么就需要转义符

  1. $ pwd | sed 's/\/home/\/myhome/'
  2. /myhome/su1216/android/source/linux_learned

或者,我们也可以把命令中的字符串分割符“/”给替换掉

  1. $ pwd | sed 's@home@myhome@'
  2. /myhome/suzhaoqiang/android/source/linux_learned

使用地址

默认情况下,sed会对所有行使用命令,如果只想将命令作用于特定某些行,需要使用行寻址(line addressing)

sed中有两种形式的行寻址:

1.行的数字范围

2.用文本模式来过滤出某行

两种形式都使用相同的格式来指定地址:

[address] command

也可以为特定地址将多个命令放在一起:

address {

command1

command2

command3

}

数字方式的行寻址

  1. $ cat test.txt
  2. This is a test.
  3. This is a test.
  4. This is a test.
  5. This is a test.
  6. This is a test.
  7. This is a test.
  8. This is a test.
  9.  
  10. $ sed '3,$s/This/That/' test.txt
  11. This is a test.
  12. This is a test.
  13. That is a test.
  14. That is a test.
  15. That is a test.
  16. That is a test.
  17. That is a test.

从第三行开始,到最后一行(最后一行用美元符号表示)进行替换

使用文本模式过滤器

格式如下:

/pattern/command

该命令只会作用到匹配文本模式的行上。sed在文本模式中采用正则表达式。

  1. sed '/su1216/s!home!myhome!' /etc/passwd
  2. root:x:0:0:root:/root:/bin/bash
  3. ……
  4. su1216:x:1000:1000:su1216,,,:/myhome/su1216:/bin/bash
  5. ……

组合命令

需要对单行执行多条命令的话,可以使用花括号将多条命令组合在一起

  1. $ sed '2{
  2. s/This/That/
  3. s/test/good test/
  4. }' test.txt
  5. This is a test.
  6. That is a good test.
  7. This is a test.
  8. This is a test.

删除行(delete)

删除行的命令为d,如果不指定行号,那么就全部删除。

  1. $ sed '2,4d' test.txt
  2. line 1
  3. line 5
  4. line 6

sed编辑器的模式匹配也适用于删除命令:

  1. $ sed '/line 3/d' test.txt
  2. line 1
  3. line 2
  4. line 4
  5. line 5
  6. line 6

注意:sed不会修改原始文件。

可以用两个文本模式来删除某个范围内得行。

指定的第一个文本模式会打开行删除功能,第二个会关闭行删除功能。如果没有匹配到第二个,那么后面的文本将全部删除。

如果匹配到了第二个,那么sed还会继续尝试匹配第一个,继续尝试再次打开删除功能!

  1. $ sed '/line 2/,/line 4/d' test.txt
  2. line 1
  3. line 5
  4. line 6

插入和附加文本

插入(insert)命令i会在指定行前加一个新行

追加(append)命令a会在指定行后加一个新行

格式如下:

sed '[address]command\

new line'

  1. $ echo "Line" | sed 'i\Line 1'
  2. Line 1
  3. Line
  4. $ echo "Line" | sed 'a\Line 1'
  5. Line
  6. Line 1

在数据流的最后添加新行

  1. $ sed '$a\new line' test.txt
  2. line 1
  3. line 2
  4. line 3
  5. line 4
  6. line 5
  7. line 6
  8. new line

修改行(change)

和之前的使用完全一样

使用地址区间的时候需要注意,sed会把区间中的所有内容作为一个整体用新行替换

  1. $ sed '2,4c\new line' test.txt
  2. line 1
  3. new line
  4. line 5
  5. line 6

转换命令

转换(transform,y)命令是唯一可用处理单个字符的sed编辑器命令

格式如下:

[addressly/inchars/outchars/

转换命令会对inchars和outchars按顺序做一个一一映射。

如果inchars和outchars长度不同,sed则会产生错误信息

  1. $ sed 'y/123/abc/' test.txt
  2. A:aabbaacc
  3. B:44aa55bb

转换命令是全局的,他们将所有指定的字符都替换成目标字符。

回顾打印

用来打印数据流中的信息的命令:

1.p,用来打印文本行

2.等号(=)命令,用来打印行号

3.l(小写L)命令,用来列出行

打印行

和替换命令中的p标记类似,p命令可以打印sed编辑器输出中的一行

  1. $ echo "hello" | sed 'p'
  2. hello
  3. hello
  4. $ echo "hello" | sed -n 'p'
  5. hello

也可以使用文本模式

  1. $ cat test.txt
  2. A:11221133
  3. B:44115522
  4. line 3
  5. line 4
  6. line 5
  7. $ sed -n '/line/p' test.txt
  8. line 3
  9. line 4
  10. line 5

可以与替换命令一起使用,下面是修改一行,并且打印出修改前的这一行

  1. $ sed -n '/3/{p;s/line/Line/p}' test.txt
  2. A:11221133
  3. line 3
  4. Line 3

含有3的有两行,其中后面一行满足条件,然后被替换。

打印行号

  1. $ sed '=' test.txt
  2. 1
  3. A:11221133
  4. 2
  5. B:44115522
  6. 3
  7. line 3
  8. 4
  9. line 4
  10. 5
  11. line 5

行号由换行符决定。

  1. $ sed -n '/line/{=;p}' test.txt
  2. 3
  3. line 3
  4. 4
  5. line 4
  6. 5
  7. line 5

列出行

此命令允许打印数据流中的文本和不可打印的ASCII字符。

任何不可打印字符都用他们的八进制值前加一个反斜线或标准C风格的命名法。

  1. $ sed -n 'l' test.txt
  2. A:11221133$
  3. B:44115522$
  4. line 3$
  5. line 4$
  6. line 5$

比如制表符用\t表示,行结束用$表示。

用sed和文件一起工作

向文件写入

格式如下:

[address]w filename

  1. $ sed '1,2w sed_w_test' test.txt
  2. A:11221133
  3. B:44115522
  4. line 3
  5. line 4
  6. line 5
  7. $ cat sed_w_test
  8. A:11221133
  9. B:44115522

当然,我们可以改成下面的形式

  1. $ sed -n '1,2w sed_w_test' test.txt
  2. $ cat sed_w_test
  3. A:11221133
  4. B:44115522

从文件读取数据

格式如下:

[address]r filename

读取命令允许将一个独立文件中的数据插入到数据流中。

  1. $ cat sed_w_test
  2. A:11221133
  3. B:44115522
  4. $ sed '4r sed_w_test' test.txt
  5. A:11221133
  6. B:44115522
  7. line 3
  8. line 4
  9. A:11221133
  10. B:44115522
  11. line 5

如果想插到文件末尾,可以使用$

转贴请保留以下链接

本人blog地址

http://su1216.iteye.com/

http://blog.csdn.net/su1216/

《Linux命令行与shell脚本编程大全》 第十八章 学习笔记的更多相关文章

  1. 《Linux命令行与shell脚本编程大全》 第八章管理文件系统

    8.1 探索linux文件系统 8.1.1 基本的Linux文件系统 ext:最早的文件系统,叫扩展文件系统.使用虚拟目录操作硬件设备,在物理设备上按定长的块来存储数据. 用索引节点的系统来存放虚拟目 ...

  2. Linux命令行与shell脚本编程大全.第3版(文字版) 超清文字-非扫描版 [免积分、免登录]

    此处免费下载,无需账号,无需登录,无需积分.收集自互联网,侵权通知删除. 点击下载:Linux命令行与shell脚本编程大全.第3版 (大小:约22M)

  3. 《Linux命令行与shell脚本编程大全 第3版》创建实用的脚本---11

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  4. 《Linux命令行与shell脚本编程大全 第3版》高级Shell脚本编程---47

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  5. 《Linux命令行与shell脚本编程大全 第3版》Shell脚本编程基础---57

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  6. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---57

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  7. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---56

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  8. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---55

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  9. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---54

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

  10. 《Linux命令行与shell脚本编程大全 第3版》Linux命令行---53

    以下为阅读<Linux命令行与shell脚本编程大全 第3版>的读书笔记,为了方便记录,特地与书的内容保持同步,特意做成一节一次随笔,特记录如下:

随机推荐

  1. CodeForces 260A Adding Digits

    这道题目的意思是给你提供a, b, n 三个数 a为 输入的数字 ,你需要在a后面加n次 ,每次可以加0-9 但要保证每次加上去的那个数字能被b整除 不过数据规模有点大,用搜索会MLE(即使开了个开栈 ...

  2. cocos2d-实现读取.plist文件(使用数组CCArray)

    学习札记之cocos2d-x2.1.1实现读取.plist文件(使用数组CCArray) <?xml version="1.0" encoding="UTF-8&q ...

  3. Delphi发送邮件...

    ///首先在控件栏定位到:Indy Clients加入控件IdSMTP ///再定位到:Indy Misc加入控件IdMessage ///发送邮件函数 procedure TForm1.SendMa ...

  4. Qt调用DLL

    声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的.并且用我前两篇有关DLL文章里面的方法,从dll中导出了导入库(.lib)文件,dll中有两个函数,原型如下:   ...

  5. new Handler().postDelayed() 延迟intent跳转

    原文地址http://blog.csdn.net/x605940745/article/details/19401549 new Handler().postDelayed(new Runnable( ...

  6. windows phone 8的新特性

    <1>硬件的升级WP8在硬件上有了极大的提升,处理器支持双核或多核 理论最大支持64核,分辨率支持800x480.1280x720/768,屏幕支持720p或WXGA:支持存储卡扩展.同时 ...

  7. JVM调优总结(十二)-参考资料

    能整理出上面一些东西,也是因为站在巨人的肩上.下面是一些参考资料,供大家学习,大家有更好的,可以继续完善:) · Java 理论与实践: 垃圾收集简史 · Java SE 6 HotSpot[tm] ...

  8. Agg vs. Cairo 二维绘图引擎之比较和选择 .

    Agg vs. Cairo 二维绘图引擎之比较和选择 cheungmine 当今时代对于作为二维图形软件开发者, 是幸运的.因为除了Windows GDI/GDI+之外,我们还有很多其他的选择.而且这 ...

  9. Cocos2d-x CCTableView实现列表

    在ios程序设计中,会大量使用到tableview视图(UITableView),那么在cocos2d-x中,如果需要类似的列表,该如何实现呢?在引擎中参照ios中的UITableView实现了一个叫 ...

  10. 《高质量程序设计指南:C++/C语言》面试题整理

    本试题仅用于考查C++/C程序员的基本编程技能.内容限于C++/C常用 语法,不涉及 数据结构. 算法以及深奥的语法.考试成绩能反映出考生的编程质量以及对C++/C的理解程度,但不能反映考生的智力和软 ...