AWK

# ll /usr/bin/awk
lrwxrwxrwx. 1 root root 14 Sep 3 03:33 /usr/bin/awk -> ../../bin/gawk

awk其实是一门编程语言,它支持条件判断、数组、循环等功能。所以,我们也可以把awk理解成一个脚本语言解释器。

grep 更适合单纯的查找或匹配文本

sed  更适合编辑匹配到的文本

awk  更适合格式化文本,对文本进行较复杂格式处理

awk是逐行处理的,逐行处理的意思就是说,当awk处理一个文本时,会一行一行进行处理,处理完当前行,再处理下一行,awk默认以"换行符"为标记,识别每一行,也就是说,awk跟我们人类一样,每次遇到"回车换行",就认为是当前行的结束,新的一行的开始,awk会按照用户指定的分割符去分割当前行,如果没有指定分割符,默认使用空格作为分隔符。

语法

awk [options] 'Pattern{Action}' file

# awk -W help
Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
POSIX options:          GNU long options:
        -f progfile             --file=progfile
        -F fs                   --field-separator=fs
        -v var=val              --assign=var=val
        -m[fr] val
        -O                      --optimize
        -W compat               --compat
        -W copyleft             --copyleft
        -W copyright            --copyright
        -W dump-variables[=file]        --dump-variables[=file]
        -W exec=file            --exec=file
        -W gen-po               --gen-po
        -W help                 --help
        -W lint[=fatal]         --lint[=fatal]
        -W lint-old             --lint-old
        -W non-decimal-data     --non-decimal-data
        -W profile[=file]       --profile[=file]
        -W posix                --posix
        -W re-interval          --re-interval
        -W source=program-text  --source=program-text
        -W traditional          --traditional
        -W usage                --usage
        -W use-lc-numeric       --use-lc-numeric
        -W version              --version

To report bugs, see node `Bugs' in `gawk.info', which is
section `Reporting Problems and Bugs' in the printed version.

gawk is a pattern scanning and processing language.
By default it reads standard input and writes standard output.

Examples:
        gawk '{ sum += $1 }; END { print sum }' file
        gawk -F: '{ print $1 }' /etc/passwd

print 

# cat test
[Wed Oct 23 10:59:46 2019]
[Wed Oct 23 10:59:46 2019]
# awk '{print $1,$2}'  test
[Wed Oct
[Wed Oct

$0 表示显示整行 ,$NF表示当前行分割后的最后一列($0和$NF均为内置变量)

# awk '{print $1,$2,$NF}'  test
[Wed Oct 2019]
[Wed Oct 2019]

除了输出文本中的列,还能够添加自己的字段,将自己的字段与文件中的列结合起来

# awk '{print $1 "星期三",$2 "10月",$NF "年"}'  test
[Wed星期三 Oct10月 2019]年
[Wed星期三 Oct10月 2019]年

$1这种内置变量的外侧不能加入双引号,否则$1会被当做文本输出


BEGIN和END

# awk 'BEGIN{print "星期","月","年"} {print $1,$2,$NF}'  test
星期 月 年
[Wed Oct 2019]
[Wed Oct 2019]
# awk 'BEGIN{print "星期","月","年"} {print $1,$2,$NF} END{print "三","十","年"}'  test
星期 月 年
[Wed Oct 2019]
[Wed Oct 2019]
三 十 年

NF分隔符

输入分隔符,英文原文为field separator,此处简称为FS

输入分割符,默认是空白字符(即空格),awk默认以空白字符为分隔符对每一行进行分割。 

输出分割符,英文原文为output field separator,此处简称为OFS

awk将每行分割后,输出在屏幕上的时候,以什么字符作为分隔符,awk默认的输出分割符也是空格

# cat  test
[Wed Oct 23 10:59:46 2019]
[Wed Oct 23 10:59:46 2019]
# awk -F 2 '{print $1"--"$2"--"$3}' test
[Wed Oct --3 10:59:46 --019]
[Wed Oct --3 10:59:46 --019]

变量

内置变量

$n当前记录的第n个字段,字段间由FS分隔
$0完整的输入记录
ARGC命令行参数的数目
ARGIND命令行中当前文件的位置(从0开始算)
ARGV包含命令行参数的数组
CONVFMT数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO最后一个系统错误的描述
FIELDWIDTHS字段宽度列表(用空格键分隔)
FILENAME当前文件名
FNR各文件分别计数的行号
FS字段分隔符(默认是任何空格)
IGNORECASE如果为真,则进行忽略大小写的匹配
NF一条记录的字段的数目
NR已经读出的记录数,就是行号,从1开始
OFMT数字的输出格式(默认值是%.6g)
OFS输出记录分隔符(输出换行符),输出时用指定的符号代替换行符
ORS输出记录分隔符(默认值是一个换行符)
RLENGTH由match函数所匹配的字符串的长度
RS记录分隔符(默认是一个换行符)
RSTART由match函数所匹配的字符串的第一个位置
SUBSEP数组下标分隔符(默认值是/034)

内置变量NR

变量NR表示每一行的行号,内置变量NF表示每一行中一共有几列

# cat test
[Wed Oct 23 10:59:46 2019]
[Wed Oct 23 10:59:46 2019]
# awk '{print NR,NF}' test
1 5
2 5

内置变量FNR

各文件分别计数的行号

# awk '{print FNR,$0}' test test2
1 [Wed Oct 23 10:59:46 2019]
2 [Wed Oct 23 10:59:46 2019]
1 total 16
2 -rw-r--r-- 1 root root 1991 Oct 23 11:03 access_log
3 -rw-r--r-- 1 root root 1614 Oct 23 11:00 error_log
4 -rw-r--r-- 1 root root    0 Oct 23 10:59 ssl_access_log
5 -rw-r--r-- 1 root root  220 Oct 23 10:59 ssl_error_log

内置变量RS

RS是输入行分隔符,如果不指定,默认的"行分隔符"就是我们所理解的"回车换行"。

# awk -v RS=" " '{print FNR,$0}' test
1 [Wed
2 Oct
3 23
4 10:59:46
5 2019]
[Wed
6 Oct
7 23
8 10:59:46
9 2019]

内置变量ORS

输出行分隔符

# awk -v ORS="/**/" '{print FNR,$0}' test
1 [Wed Oct 23 10:59:46 2019]/**/2 [Wed Oct 23 10:59:46 2019]/**/

内置变量FILENAME

# awk '{print FILENAME}' test
test
test

内置变量ARGC与ARGV

ARGC:命令行参数的个数

# awk '{print ARGC}' test
2
2

ARGV:数组,保存的是命令行所给定的各参数

# awk '{print ARGV[1]}' test
test
test
# awk '{print ARGV[0]}' test
awk
awk

awk就是这么规定的,'pattern{ action }'并不被看做是参数,awk被看做为参数。

自定义变量

方法一:-v varname=value  变量名区分字符大小写。

方法二:在program中直接定义。

# awk -v myVar="testVar" 'BEGIN{print myVar}' test
testVar
# awk 'BEGIN{myVar="testVar"; print myVar}' test
testVar

printf

printf命令的作用是安装指定的格式输出文本

# awk '{printf "%-8s %-10s\n",$2,$4}' test
Oct      10:59:46
Oct      10:59:46  

运算符

= += -= *= /= %= ^= **=赋值
?:C条件表达式
||逻辑或
&&逻辑与
~ 和 !~匹配正则表达式和不匹配正则表达式
< <= > >= != ==关系运算符
空格连接
+ -加,减
* / %乘,除与求余
+ - !一元加,减和逻辑非
^ ***求幂
++ --增加或减少,作为前缀或后缀
$字段引用
in数组成员


 内置函数

 https://www.runoob.com/w3cnote/awk-built-in-functions.html

---恢复内容结束---

12-30 01:56