shell脚本最常见的一个用途就是处理文本文件。但仅靠shell脚本命令来处理文本文件的内容有点勉为其难。Linux中的sed和gawk工具能够极大简化需要进行的数据处理任务。
第10章演示了如何用Linux环境中的编辑器程序来编辑文本文件。这些编辑器可以让你用简 单命令或鼠标单击来轻松地处理文本文件中的文本。
但有时候,你会发现需要自动处理文本文件,可你又不想动用全副武装的交互式文本编辑器。 在这种情况下,有个能够轻松实现自动格式化、插入、修改或删除文本元素的简单命令行编辑器 就方便多了。
Linux系统提供了两个常见的具备上述功能的工具。本节将会介绍Linux世界中最广泛使用的两个命令行编辑器:sed和gawk。
<一>sed 编辑器
【简介】
sed编辑器被称作流编辑器(stream editor),和普通的交互式文本编辑器恰好相反。在交互式文本编辑器中(比如vim),你可以用键盘命令来交互式地插入、删除或替换数据中的文本。流编辑器则会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。
【sed工作流程】
sed编辑器会重复执行下列操作,处理完流中的所有数据行后终止:
(1) 一次从输入(默认STDIN输入流)中读取一行数据
(2) 根据所提供的编辑器命令匹配数据
(3) 按照命令修改流中的数据
(4) 将新的数据输出到STDOUT
由以上流程可知,处理数据,sed编辑器只需遍历一次数据流。
【命令格式】
sed options script file
<1> options参数:
①-e可以执行多个命令,命令之间分号分割
②-f可以读取脚本文件中命令
脚本文件每条命令一行,无需分号。sed编辑器按行识别。
<2> sed命令
①替换:使用s命令在行中替换脚本
s/pattern/replacement/flags
使用repalcement替换pattern,默认只替换每行的第一个pattern。flags参数可以更改替换方式:
数字,表明新文本将替换第几处模式匹配的地方;
g,表明新文本将会替换所有匹配的文本;
p,表明原先行的内容要打印出来;
w file,将替换的结果写到文件中。
eg:pig替换test
替换特殊字符使用\进行转义。
②删除:使用d命令删除匹配行(无匹配全删)
sed '数字d' file #删除第"数字"行
sed '/pattern/d' file #删除包含pattern的行
不建议使用两个文本模式来删除某个区间内的行。两个文本模式中,匹配到"模式一"开始删除,到"模式二"关闭删除。若开始删除后未匹配到关闭模式,后续会全部删除。
如图,第一次删除了匹配到1和3之间的数据行 ,第二次未匹配到3,则后续行全部被删除。
③插入
sed '数字i\ new_line' file #第"数字"行前插入new_line
sed '数字a\ new_line' file #第"数字"行后插入new_line
④修改
sed '数字c replacement' file #修改第"数字"行为replacement
sed '/pattern/c replacement' file #修改包含pattern的行为replacement
注:
- 以上操作只影响sed编辑器的输出,不修改原始文件。
- 为清晰识别sed编辑器脚本与bash shell脚本,使用.sed作为sed脚本文件的扩展名。
<二> awk
【简介】
awk是处理文本文件的一个应用程序(几乎所有 Linux 系统都自带这个程序),也是一门语言。
awk可以使用options参数 或 'program' 中写入程序。
【工作流程】
同sed,awk读取命令行上指定的各个文件(没有,则读取标准输入),awk每接收文件的一行,就执行相应的命令。
【命令格式】
awk options 'program' file
eg: awk -F : '{print $2}' a.txt #以":"分隔a.txt,打印第二列
options参数:
-F 指定字段分隔符,不指定默认是空格和制表符;
-f 从指定文件中读取程序;
-v 自定义变量。
【变量】
数据字段变量
awk在读取一行文本时,会用预定义的字段分隔符划分每个数据字段,并自动给一行中的每个数据元素分配一个变量。"$数字"
表示第某个字段
$0代表整个文本行;
$1代表文本行中的第1个数据字段;
$2代表文本行中的第2个数据字段;
awk内置变量:
NR:
表示当前处理的是第几行;
NF:
表示当前行有多少个字段;
FS
:(输入)字段分隔符,默认空格和制表符,等价于命令行-F参数;
RS
:(输入)行分隔符,用于分割每一行,默认是一个换行符;
OFS
:(输出)字段分隔符,默认空格;
ORS
:(输出)记录的分隔符,用于打印时分隔记录,默认为一个换行符。
-v 自定义变量
【条件】
awk options '{pattern + action}' file
'program'可以进一步拆解为'{pattern + action}'。
pattern表示awk在数据中匹配的内容(pattern可以是正则表达式,需用斜杠"//"括起来)。
action 是在找到匹配内容时所执行的命令。
~ 表示模式(pattern)开始
eg1: awk -F ':' '/test/ {print $0}' a.txt
如eg1,按":"分割,输出包含test的文本行。
eg2: awk -F ':' '$2 ~ /test/ {print $0}' a.txt
如eg2,按":"分割,输出第二列包含test的文本行。
【多命令】
awk使用多条命令组合,在命令之间用分号分隔。比如替换第2列然后输出第2列。
【从脚本读取程序】
-f参数指定脚本,脚本中多条命令分行,不需要分号 。
【读取数据前运行脚本】
默认情况下,awk会从输入中读取一行文本,然后针对该行的数据执行程序脚本。BEGIN 关键字会强制awk在读取数据前执行BEGIN关键字后指定的程序脚本。
【处理数据后运行脚本】
与BEGIN关键字类似,END关键字允许你指定一个程序脚本,gawk会在读完数据后执行它。