文本处理
只使用shell脚本命令处理文本文件的内容有些麻烦,如果要在shell脚本中进行任意类型的数据处理,就要熟知Linux中线条有的处理文本文件的工具。下面学习的Linux环境下最常用的两个命令行编辑器:sed和gawk.
①初识sed编辑器
sed编辑器称为流编辑器,流编辑器将根据在编辑器处理数据之前事先提供的规则集编辑数据流。
sed命令格式为:
sed options script file
选项 | 描述 |
---|---|
-e script | 使用脚本中的命令处理数据(多用于命令行中使用多个命令) |
-f file | 将文件中的命令添加到处理输入时执行的命令中 |
-n | 禁止输出,等待打印 |
举个例子:
$ cat data
There ara two tests
$ sed -e 's/two/five/';s/tests/questions/' data
There ara five questions
两个命令同时使用时,注意命令必须用分号隔开,而且在命令结尾和分号之间不能有任何空格。
如果使用次提示符的时候,只需要输入前单引号打开脚本,bash将继续提示你输入更多的命令,直到输入后单引号。 注意要在后单引号出现的同一行上完成该命令。
$ sed -e '
> s/dog/cat/
> s/fox/fish/' data
使用从文件读取编辑器命令时,sed知道一行包含单独一个命令。
$ cat script
s/two/five/
s/test/questions/
$ sed -f script data
There ara five questions
sed编辑器并不修改文本文件中的数据,它只是将修改后的文本发送到STOUT,原文件不会被修改。
②sed编辑器进阶
替换标志
在使用替换命令时,默认只会替换每一行出现的第一个文本,如果要按需要替换相应的文本需要使用替换标记。
★ 数字:表示替换每一行的第几个文本
★ g:替换所有文本
★ p : 表示打印原始行的内容(使用-n和p替换标志,仅生成替换命令已经更改的那些行)
★ w file :将替换写入原文件
格式:
s/被替换的文本/替换的新文本/替换标记
为了避免混淆,允许使用!替换/作界定符。
$ sed 's!/bin/bash!/bin/csh!' /etc/passwd
使用地址
$ sed '2,3s/dog/cat/' data1 #运用替换文本中2到3行的指定值
$ sed '2,$s/dog/cat/' data1 #运用替换文本中从第二行到结束的指定值
$ sed '/rich/s/bash/csh' /etc/passwd #只更改用户rich后面的值
删除行
$ sed '/1/,/3/d' data2 #从包含数字1的行开始,到包含3的行之后结束这些行都被删除(注意出现再次检测到包含1的行产生误删)
插入、附加、更该行和变换命令
★ 插入命令(i)在指定行之前添加
★ 附加命令(a)在指定行之后添加
★ 更该行(c)更改指定行的内容
$ sed '$a/
>hello/
> bybe' data
$ sed '1i/
>hello' data
★ 变换命令(y)将inchars的每一个字符更改为outchars的没一个字符
sed 'y/inchars/outchars/' file
打印命令、读写命令
★ 打印行号使用‘=’
★ 写命令的格式:[address]r filename
★ 读命令的格式:[address]w filename
举个例子:
$ sed '1,2w test' data #将data中的1到2行写入test中
$ cat data11
This is a boy
$ cat data12
This
An
hello
$ sed '/An/{
> r data11
> d
> }' data12
This
This is a boy
hello
③初识gawk程序
gawk程序是一个能够提供类似于编程环境的工具,它允许修改和重新组织文件中的数据。
举几个例子来看看gawk是如何使用的:
自命令行读取程序脚本。
使用gawk打印功能时。它不会立刻执行,需要在有一个数据输入后才执行,要想退出gawk程序,需要按下组合件Ctrl+D(生成EOF字符)。
$ gawk '{print "hello"}'
This is a test
hello
This
hello
使用数据字段变量
$0 表示整行文本
$n 表示文本行中的第n个数据字段(默认字段分隔符是空白字符)
如果需要使用不同字段分隔符,可以使用-F选项指定:
$ gawk -F: '{print $1}' /etc/passwd
root
bin
...
使用BEGIN关键字使得在输入前输出文本,使用END关键字使得在处理数据之后运行脚本。文件内置定义分隔符为 FS=“分隔符”
其读取文件中命令方式与sed类似,在这里就不赘述了。
$ gawk 'BEGIN {hello} {boy}'
hello boy
$ gawk 'END {hello} {boy}'
This is a test
(Ctrl+D)
hello boy