19. 初识sed和gawk

19. 初识sed和gawk

19.1 文本处理

19.1.1 sed编辑器

sed编辑器被称作流编辑器(stream editor),执行操作如下:

(1) 一次从输入中读取一行数据。 
(2) 根据所提供的编辑器命令匹配数据。 
(3) 按照命令修改流中的数据。 
(4) 将新的数据输出到STDOUT。
sed options script file

script参数指定了应用于流数据上的单个命令。如果需要用多个命令,要么使用-e选项在命令行中指定,要么使用-f选项在单独的文件中指定。

1.在命令行定义编辑器命令

echo "This is a test" | sed 's/test/big test/'

使用了s命令。s命令会用斜线间指定的第二个文本字符串来替换第一个文本字符串模式。在本例中是big test替换了test
sed不会修改文本文件的数据。它只会将修改后的数据发送到STDOUT。如果你查看原来的文本文件,它仍然保留着原始数据。

2.在命令行使用多个编辑器命令
要在sed命令行上执行多个命令时,只要用-e选项就可以了。

两个命令都作用到文件中的每行数据上。命令之间必须用分号隔开,并且在命令末尾和分号之间不能有空格。

sed -e 's/brown/green/; s/dog/cat/' data1.txt

如果不想用分号,也可以用bash shell中的次提示符来分隔命令。只要输入第一个单引号标示出sed程序脚本的起始(sed编辑器命令列表),bash会继续提示你输入更多命令,直到输入了标示结束的单引号。

sed -e ' 
> s/brown/green/ 
> s/fox/elephant/ 
> s/dog/cat/' data1.txt

3.从文件中读取编辑器命令

sed -f 命令存储文件  待处理语句的文件
19.1.2 gawk程序

1.gawk命令格式

gawk options program file

gawk的强大之处在于程序脚本。可以写脚本来读取文本行的数据,然后处理并显示数据,创建任何类型的输出报告。
gawk选项
2.从命令行读取程序脚本
gawk程序脚本用一对花括号来定义。你必须将脚本命令放到两个花括号({})中。

gawk '{print "Hello World!"}'

由于没有在命令行上指定文件名,所以gawk程序会从STDIN接收数据一直等待,然后将文本打印到STDOUT。最后Ctrl + D可以终止STDIN

3.使用数据字段变量
它会自动给一行中的每个数据元素分配一个变量
$0代表整个文本行;
$1代表文本行中的第1个数据字段;
$2代表文本行中的第2个数据字段;
$n代表文本行中的第n个数据字段。
例如,首先编写文本文件data2.txt

One line of test text. 
Two lines of test text. 
Three lines of test text.

然后打印每一行的第一个字段

gawk '{print $1}' data2.txt

但是有可能字段并不是以空格为分隔符,这个时候需要使用-F选项指定分割字符,具体使用可以参照下面指定:为分隔符的命令

gawk -F: '{print $1}' /etc/passwd

4. 在程序脚本中使用多个命令
例如打印一段字符串然后替换其中第四个字段并重新打印

echo "My name is Rich" | gawk '{$4="Christine"; print $0}'

也可以直接输入后面然后等待STDIN

$ gawk '{ 
> $4="Christine" 
> print $0}'

5. 从文件读取程序
编写程序文件script3.gawk

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

在命令行使用-f选项指定程序文件

gawk -F: -f script3.gawk /etc/passwd

6. 在处理数据前运行脚本
gawk在读取数据前执行BEGIN关键字后指定的程序脚本

gawk 'BEGIN {print "The data3 File Contents:"} 
> {print $0}' data3.txt

7. 在处理数据后运行脚本

$ gawk 'BEGIN {print "The data3 File Contents:"} 
> {print $0} 
> END {print "End of File"}' data3.txt

19.2 Sed编辑器基础

19.2.1 更多的替换选项

s命令只替换每行中出现的第一处。要让替换命令能够替换一行中不同地方出现的文本必须使用替换标记
命令格式:s/pattern/replacement/flags
替换标记:
数字,表明新文本将替换第几处模式匹配的地方;
g,表明新文本将会替换所有匹配的文本;
p,表明原先行的内容要打印出来;
w file,将替换的结果写到文件中。

执行结果:
1.创建一个待处理的文本data2.txt

One line of test text final text line
Two lines of test text final text line
Three lines of test text final text line

2.执行对应命令

$ sed 's/line/line_flag/2' data2.txt
One line of test text final text line_flag
Two lines of test text final text line_flag
Three lines of test text final text line_flag
$ sed 's/line/line_flag/g' data2.txt
One line_flag of test text final text line_flag
Two line_flags of test text final text line_flag
Three line_flags of test text final text line_flag

-n选项禁止sed编辑器输出,p替换标记会输出修改过的行,结合一下就会输出被替换命令修改的行,w替换标记相同,但是会输出到指定文件。

替换字符
不太方便替换的如/,这个符号作为替换字符串之间的分割符号,在路径替换中如果想用C shell替换/etc/passwd文件中的bash shell,必须按照:

sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd

当然也可以使用其他字符作为替换字符串之间的分隔符号,例如

sed 's!/bin/bash!/bin/csh!' /etc/passwd
19.2.2使用地址

默认情况下,在sed编辑器中使用的命令会作用于文本数据的所有行。如果只想将命令作用于特定行或某些行,则必须用行寻址。

在sed编辑器中有两种形式的行寻址:
1.以数字形式表示行区间
2.用文本模式来过滤出行
命令格式:[address]command
多个命令分组:address { command1 command2 command3}

1.数字方式行寻址

指定单行: sed '2s/dog/cat/' data1.txtdata1.txt第2行的dog换成cat。
指定行区间: sed '2,3s/dog/cat/' data1.txtdata1.txt第2行到第3行的dog换成cat。
指定从当行之后的所有行: sed '2,$s/dog/cat/' data1.txtdata1.txt第2行到之后的所有行的dog换成cat。

2.使用文本模式过滤器
按照模式命令过滤,作用在指定文本模式pattern的行上:/pattern/command
例如:sed '/Samantha/s/bash/csh/' /etc/passwdSamantha中的bash换成csh

3.命令组合
使用花括号{}将多条命令组合在一起

$ sed '2{ 
> s/fox/elephant/ 
> s/dog/cat/ 
> }' data1.txt
19.2.3 删除行

删除选项d,同样可以采用数字和文本模式两个指令

$cat data2.txt
One line of test text final text line
Two lines of test text final text line
Three lines of test text final text line

$sed '2d' data2.txt
One line of test text final text line
Three lines of test text final text line

sed '/One line/d' data2.txt
Two lines of test text final text line
Three lines of test text final text line

注意如果使用两个文本模式,第一个是开始删除,第二个是结束删除,但是注意有可能多个地方匹配了开始却不一定能匹配结束。

$ cat data7.txt 
This is line number 1. 
This is line number 2. 
This is line number 3. 
This is line number 4. 
This is line number 1 again. 
This is text you want to keep. 
This is the last line in the file. 
$ sed '/1/,/3/d' data7.txt 
This is line number 4.

有两个地方匹配了开始删除,但是只有第3行匹配了结束,因此最后剩下第4行。

19.2.4 插入和附加文本

插入(insert):i 会在指定行前增加一个新行;
附加(append):a 会在指定行后增加一个新行。

$echo "Test Line 2" | sed 'i\Test Line 1' 
Test Line 1 
Test Line 2

$ echo "Test Line 2" | sed 'a\Test Line 1' 
Test Line 2 
Test Line 1

同样可以采用指定行或者对应的文本模式插入,例如:

$ sed '3i\ 
> This is an inserted line.' data6.txt 
This is line number 1. 
This is line number 2. 
This is an inserted line. 
This is line number 3. 
This is line number 4.

sed '$a\ 
> This is a new line of text.' data6.txt 
This is line number 1. 
This is line number 2. 
This is line number 3. 
This is line number 4. 
This is a new line of text.
19.2.5 修改行

c指令

$ cat data8.txt
This is line number 1
This is line number 2
This is line number 3
This is line number 4

$ sed '/number 1/c This is a' data8.txt
This is a
This is line number 2
This is line number 3
This is line number 4

$ sed '2,3c This is a new line of text.' data8.txt
This is line number 1
This is a new line of text.
This is line number 4
19.2.6 转换命令

转换命令是一个全局命令,也就是说,它会文本行中找到的所有指定字符自动进行转换,而不会考虑它们出现的位置。

[address]y/inchars/outchars/

会建立起inchars和outchars每个字符的对应,因此必须保证长度一致。

19.2.6 转换命令

1.打印行
-n禁止输出其他行

$ cat data6.txt 
This is line number 1. 
This is line number 2. 
This is line number 3. 
This is line number 4. 
$ 
$ sed -n '/number 3/p' data6.txt 
This is line number 3.

2.打印行号
=会打印在数据流的当前行号,由换行符决定

sed -n '/number 1/{
> =
> p
> }' data8.txt
1
This is line number 1

3.列出行号
使用l指令打印数据流中的文本和不可打印的ASCII字符

19.2.8 使用sed处理文件

1.向文件中编写数据
命令格式:[address]w filename

$ sed '1,2w test_set.txt' data8.txt
This is line number 1
This is line number 2
This is line number 3
This is line number 4

2.从文件中读取数据
命令格式:[address]r filename
filename的文件中读取数据插入指定位置之后


$ cat data12.txt 
This is an added line. 
This is the second added line. 
#将文件data12.txt中的数据读取插入到data6.txt第三行之后
$ sed '3r data12.txt' data6.txt 
This is line number 1. 
This is line number 2. 
This is line number 3. 
This is an added line. 
This is the second added line. 
This is line number 4.

#将文件data12.txt中的数据读取插入到data6.txt数据流末尾
$ sed '$r data12.txt' data6.txt 
This is line number 1. 
This is line number 2. 
This is line number 3. 
This is line number 4. 
This is an added line. 
This is the second added line.

-d结合删除指定占位符

$ cat notice.std 
Would the following people: 
LIST 
please report to the ship's captain.

$ sed '/LIST/{ 
> r data11.txt 
> d 
> }' notice.std 
Would the following people: 
Blum, R       Browncoat 
McGuiness, A  Alliance 
Bresnahan, C  Browncoat 
Harken, C     Alliance 
please report to the ship's captain.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值