实践中学习 awk
文章目录
[隐藏]
- 内置变量
- 记录
- 域
- awk 命令格式
- 域分隔符
- 模式-Pattern
- awk 内建函数
内置变量
awk 中预先定义好的,内置在 awk 内部的变量。
记录
1、awk 把每一个换行符结束的行称为一个记录,$0 变量:它指的是整条记录。
# 输出 test.txt 文件中的所有记录 awk '{print $0}' test.txt
2、变量 NR:一个计数器,每处理完一条记录,NR 的值就增加 1。
# 输出 test.txt 中的所有记录,并在记录前显示行号 awk '{print NR, $0}' test.txt
域
记录中的每个单词都称作「域」,默认情况下以空格分隔。awk 可跟踪域的个数,并在内建变量 NF 中保存该值。
# 打印第一和第三个以空格分开的列(域) awk '{print $1, $3}' test.txt
awk 命令格式
有了上边域和记录的概念,来看看 awk 的命令格式:
awk [options] 'pattern{action}' file
eg1:
# $3 == 0:是 pattern # print $0:是 action awk '$3==0 {print $0}' employee # 如果第三个域等于 0,则将这行打印
eg2:
下面这个 awk 脚本没有指定 action,但结果和 eg1 一样,没有指定 action 时默认是 {print $0}(打印整行)。
awk '$3 == 0' employee
eg3:
#将结果重定向到文件 awk '$3 == 0' employee > other.txt
域分隔符
1、输入分隔符(field separator),就是 test.txt 中每个列是以什么进行分隔的,awk 默认以空格对每一行进行分隔,分隔符得值保存在内建变量 FS中,可以通过-F命令行选项修改FS的值。
# 指定 : 作为分隔符 awk -F: '{print $1, $3}' test.txt # 显示指定空格作为分隔符 awk -F'[ ]' '{print $1, $3}' test.txt # 指定空格、冒号、tab 作为分隔符 awk -F'[:t ]' '{print $1, $3}' test.txt # 指定以逗号(,)作为分隔符 awk -F, '{print $1, $2}' separator.txt # 使用 -v 选项对内建变量设置分隔符,和 awk -F, 效果一样 awk -v FS=',' '{print $1, $2}' separator.txt
2、输出分隔符(out field separator), 大白话表示就是 awk 在处理完文本后以什么字符作为分隔符将每行输出,默认也是空格,保存在内建变量 OFS 中。
eg1:
# 对内建变量 OFS 赋值 awk -v OFS="->" '{print $1, $2, $3}' other.txt
输出如:
Beth->4.00->0 Dan->3.75->0
eg2:
# 同时指定输入和输出分隔符 awk -v FS=',' -v OFS='->' '{print $1, $2}' separator.txt
模式-Pattern
根据前面的一些例子,awk 的语法如下:
awk [options] 'Pattern {Action}' file1 file2 options(选项): 如前面使用过的 -v -F Action(动作):如 print
Pattern:也就是条件,一个关系表达式,awk 会逐行处理文本,处理完当前行,然后再处理下一行。如果不指定任何的「条件」,awk 会一行一行的处理完文件的每一行,如果指定了「条件」,只处理满足条件的行。这即 awk 中的模式。
# 将有四列的行打印出来 awk 'NF == 4 {print $0}' column.txt # 没有指定模式则是空模式,空模式会匹配文本中每一行,每一行都满足条件 awk '{print $0}' test.txt
1、正则模式
# 将包含 in 的记录行进行打印 awk '/in/ {print $0}' pattern.txt
2、行范围模式
eg1:
# 从第一行 到 正则匹配到的第一行 之间的所有行进行打印 awk 'NR == 1, /in/{print $0}' pattern.txt # /xx/ 没有匹配到第二个模式,打印第一个模式出现的行到文本末尾 awk 'NR == 1, /xx/{print NR, $0}' pattern.txt
看一下结果:
eg2:
# 将第一行 到 正则匹配到的第一行中的 in 替换为 on(从记录行的左边开始,只替换一次) # 怎么理解这个 1 呢? # 这里有两个模式,awk 读出每行记录都会经过这两个模式的判断 # 1 表示这个模式为真,没有指定模式默认的 action 就是打印整行 awk 'NR == 1,/in/{sub(/in/, "on")} 1' pattern.txt
再来一波例子估计就懂 eg2 中的用法了:
在 1 处,模式指定为 1 表示为真,走默认的 action 打印整行。
在 2 处,指定了两个模式,每行记录都会经过这两个模式的处理,然后分别执行模式自己的动作。
在 3 处,有 3 个模式:BEGIN 模式和 END 模式,中间的是空模式(没有指定模式)。BEGIN 模式:处理文本之前先执行的操作;END 模式:处理完所有行后需要执行的操作。
范围模式的第一个模式和第二个模式都以第一次匹配到的行为准。
awk 内建函数
字符串函数
1、sub
sub (regular expression, substitution string): sub (regular expression, substitution string, target string)
对每一个记录行从左到右第一个匹配到的域进行替换,每一行只会匹配替换一次。
# 将每行第一次出现的域 hello 替换为 hi,每行只会匹配替换一次 awk '{sub(/hello/, "hi"); print}' test.txt # 对每行的第一个域进行替换 awk '{sub(/hello/, "hi", $1); print}' test.txt
原文出处:csdn -> https://blog.csdn.net/jiaobuchong/article/details/83037467