第十八章:初识sed和gawk

文本处理

sed编辑器

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

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

sed options script file

sed命令选项

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

在命令行定义编辑器命令

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

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

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

使用-e即可。

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

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

从文件中读取编辑器命令

$ cat sed_script
s/brown/white/
s/fox/elephant/

使用-f选项即可。

$ echo "The quick brown fox jumps over the lazy dog." | sed -f sed_script
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命令行假定脚本是单个文本字符串,所以必须将脚本放到单引号中。

$ gawk '{print "Hello"}'

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

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

使用数据字段变量

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

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

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

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

使用-F选项指定分隔符

$ gawk -F : '{print $1}' /etc/passwd
root
daemon
bin
sys
……

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

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

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

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

从文件中读取程序

$ cat gawk_test
{
text="'s home directory is "
print $1 text $6
}

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

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

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

在处理数据前运行脚本

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

$ gawk 'BEGIN { print "hello world"}'
hello world

在处理数据后运行脚本

当然是使用END关键字了

$ cat gawk_test
BEGIN {
print "Before read the file"
FS=":"
} {
print $1
} END {
print "The End"
}

注意:使用FS设置分割符

$ gawk -f gawk_test /etc/passwd
Before read the file
root
daemon
……
sshd
Debian-exim
The End

sed编辑器基础

更多的替换选项

替换标记

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

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

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

s/pattern/replacement/flags

有4种替换标记:

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

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

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

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

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

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

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

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

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

替换字符

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

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

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

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

使用地址

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

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

1.行的数字范围

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

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

[address] command

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

address {

command1

command2

command3

}

数字方式的行寻址

$ cat test.txt
This is a test.
This is a test.
This is a test.
This is a test.
This is a test.
This is a test.
This is a test. $ sed '3,$s/This/That/' test.txt
This is a test.
This is a test.
That is a test.
That is a test.
That is a test.
That is a test.
That is a test.

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

使用文本模式过滤器

格式如下:

/pattern/command

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

sed '/su1216/s!home!myhome!' /etc/passwd
root:x:0:0:root:/root:/bin/bash
……
su1216:x:1000:1000:su1216,,,:/myhome/su1216:/bin/bash
……

组合命令

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

$ sed '2{
s/This/That/
s/test/good test/
}' test.txt
This is a test.
That is a good test.
This is a test.
This is a test.

删除行(delete)

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

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

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

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

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

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

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

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

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

插入和附加文本

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

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

格式如下:

sed '[address]command\

new line'

$ echo "Line" | sed 'i\Line 1'
Line 1
Line
$ echo "Line" | sed 'a\Line 1'
Line
Line 1

在数据流的最后添加新行

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

修改行(change)

和之前的使用完全一样

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

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

转换命令

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

格式如下:

[addressly/inchars/outchars/

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

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

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

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

回顾打印

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

1.p,用来打印文本行

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

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

打印行

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

$ echo "hello" | sed 'p'
hello
hello
$ echo "hello" | sed -n 'p'
hello

也可以使用文本模式

$ cat test.txt
A:11221133
B:44115522
line 3
line 4
line 5
$ sed -n '/line/p' test.txt
line 3
line 4
line 5

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

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

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

打印行号

$ sed '=' test.txt
1
A:11221133
2
B:44115522
3
line 3
4
line 4
5
line 5

行号由换行符决定。

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

列出行

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

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

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

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

用sed和文件一起工作

向文件写入

格式如下:

[address]w filename

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

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

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

从文件读取数据

格式如下:

[address]r filename

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

$ cat sed_w_test
A:11221133
B:44115522
$ sed '4r sed_w_test' test.txt
A:11221133
B:44115522
line 3
line 4
A:11221133
B:44115522
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. C++ cout 如何保留小数输出

    参考 : http://upliu.net/how-cout-out-2-precision.html 大家都知道用 C 语言中 printf () 函数可以非常方便控制保留 几位小数输出 不过在 C ...

  2. QT5 动态链接库的创建和使用(QT自己做动态库给自己使用)

    记录一下QT5 动态链接库的创建和使用 在文章的最后有完成的代码供下载 1.创建动态链接库 先新建一个库项目 选择chose进入下一下页面,类型选择共享库,输入一个名称:我输入的是sld 再点击下一步 ...

  3. Jekyll学习:基本使用方法

    Jekyll是一个简单的博客.静态网站生成工具.利用它可以快速的搭建一个网站.并且完全免费的在 GitHub 上发布网站 — 自定义域名. 一.环境搭建 apt-get install jekyll ...

  4. vb和vb.net事件机制

    学习java事件前,回顾了下vb6和vb.net的事件机制,总结在这里,供对比用. 事件是面对对象中对象间通信的方法.事件发生者(又叫事件源)发生一个事件时,通过发送一条消息,给事件接受者(事件处理者 ...

  5. SVProgressHUD的使用

    GitHub:https://github.com/samvermette/SVProgressHUD SVProgressHUD和MBProgressHUD效果差点儿相同,只是不须要使用协议,同一时 ...

  6. 文件操作中的FLAG(O_RDONLY,O_WRONLY )的值

    #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> void main(void) { ...

  7. iTextSharp - 建立PDF文件

    原文 iTextSharp - 建立PDF文件 01 using iTextSharp.text; 02 using iTextSharp.text.pdf; 03 ... 04 private vo ...

  8. CString Format 乱码问题

    CString m_buf;CStatic *m_static;char *szName;...m_buf.Format(":%s",szName);m_static->Se ...

  9. android开发1:安卓开发环境搭建(eclipse+jdk+sdk)

    计划折腾折腾安卓开发了,从0开始的确很痛苦,不过相信上手应该也不会太慢.哈哈 一.Android简介 Android 是基于Linux内核的软件平台和操作系统. Android构架主要由3部分组成,l ...

  10. CxSkinButton按钮皮肤类

    在codeproject 发现一个很强大的按钮皮肤类,之前的版本有内存泄露,但是作者已经修复了,原文网址是:http://www.codeproject.com/KB/buttons/cxskinbu ...