本文链接:https://blog.csdn.net/jin970505/article/details/79056457
1、AWK简介
AWK是一种处理文本文件的语言,是一个强大的文本分析工具。
2、AWK语法
awk [选项参数] 'script' var=value file(s)
或
awk [选项参数] -f scriptfile var=value file(s)
123
或
awk [选项参数] -f scriptfile var=value file(s)
123
选项参数的说明:
-F fs or –field-separator fs
指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:
-v var=value or –asign var=value
赋值一个用户定义变量。
-f scripfile or –file scriptfile
从脚本文件中读取awk命令。
-mf nnn and -mr nnn
对nnn值设置内在限制,-mf选项限制分配给nnn的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。
-W compact or –compat, -W traditional or –traditional
在兼容模式下运行awk。所以gawk的行为和标准的awk完全一样,所有的awk扩展都被忽略。
-W copyleft or –copyleft, -W copyright or –copyright
打印简短的版权信息。
-W help or –help, -W usage or –usage
打印全部awk选项和每个选项的简短说明。
-W lint or –lint
打印不能向传统unix平台移植的结构的警告。
-W lint-old or –lint-old
打印关于不能向传统unix平台移植的结构的警告。
-W posix
打开兼容模式。但有以下限制,不识别:/x、函数关键字、func、换码序列以及当fs是一个空格时,将新行作为一个域分隔符;操作符和=不能代替^和^=;fflush无效。
-W re-interval or –re-inerval
允许间隔正则表达式的使用,参考(grep中的Posix字符类),如括号表达式[[:alpha:]]。
-W source program-text or –source program-text
使用program-text作为源代码,可与-f命令混用。
-W version or –version
打印bug报告信息的版本。
3、基本用法
一段文本:cat log.txt
2 this is a test
3 Are you like awk
This's a test
10 There are orange,apple,mongo
1234
3 Are you like awk
This's a test
10 There are orange,apple,mongo
1234
用法一:
awk ‘{[pattern] action}’ {filenames} # 行匹配语句 awk ” 只能用单引号
实例:
# 每行按空格或TAB分割(默认情况),输出文本中的1、4项
$ awk '{print $1,$4}' log.txt
---------------------------------------------
2 a
3 like
This's
10 orange,apple,mongo
---------------------------------------------
# 格式化输出
$ awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
---------------------------------------------
2 a
3 like
This's
10 orange,apple,mongo
123456789101112131415
用法二:
awk -F #-F相当于内置变量FS, 指定分割字符
实例:
# log.txt的内容如下:
# 2,this,is,a,test
# 3 Are you like awk
$ awk -F, '{print $1,$2}' log.txt
---------------------------------------------
2 this
3 Are you like awk
# 使用多个分隔符.先使用空格分割,然后对分割结果再使用","分割
$ awk -F '[ ,]' '{print $1,$2,$5}' log.txt
---------------------------------------------
2 this
3 Are
12345678910111213
$ awk -F '[ ,]' '{print $1,$2,$5}' log.txt
---------------------------------------------
2 this
3 Are
12345678910111213
用法三:
awk -v # 设置变量
实例:
$ awk -va=1 '{print $1,$1+a}' log.txt
---------------------------------------------
2 3
3 4
This's 1
10 11
$ awk -va=1 '{print $1,$(1+a)}' log.txt
---------------------------------------------
2 this
3 Are
This's a
10 There
$ awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
---------------------------------------------
2 3 2s
3 4 3s
This's 1 This'ss
10 11 10s
123456789101112131415161718
用法四:
awk -f {awk脚本} {文件名}
4、运算符
过滤第一列大于2的行:
$ awk '$1>2' log.txt #命令
#输出
3 Are you like awk
This's a test
10 There are orange,apple,mongo
12345
#输出
3 Are you like awk
This's a test
10 There are orange,apple,mongo
12345
过滤第一列等于2的行:
$ awk '$1==2 {print $1,$3}' log.txt #命令
#输出
2 is
123
#输出
2 is
123
过滤第一列大于2并且第二列等于’Are’的行:
$ awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt #命令
#输出
3 Are you
123
#输出
3 Are you
123
5、内建变量
# 输出顺序号 NR, 匹配文本行号
$ awk '{print NR,FNR,$1,$2,$3}' log.txt
---------------------------------------------
1 1 2 this is
2 2 3 Are you
3 3 This's a test
4 4 10 There are
# 指定输出分割符
$ awk '{print $1,$2,$5}' OFS=" $ " log.txt
---------------------------------------------
2 $ this $ test
3 $ Are $ awk
This's $ a $
10 $ There $
1234567891011121314
$ awk '{print NR,FNR,$1,$2,$3}' log.txt
---------------------------------------------
1 1 2 this is
2 2 3 Are you
3 3 This's a test
4 4 10 There are
# 指定输出分割符
$ awk '{print $1,$2,$5}' OFS=" $ " log.txt
---------------------------------------------
2 $ this $ test
3 $ Are $ awk
This's $ a $
10 $ There $
1234567891011121314
6、使用正则表达式
# 输出第二列包含 "th",并打印第二列与第四列
$ awk '$2 ~ /th/ {print $2,$4}' log.txt
---------------------------------------------
this a
1234
$ awk '$2 ~ /th/ {print $2,$4}' log.txt
---------------------------------------------
this a
1234
~ 表示模式开始。// 中是模式。
# 输出包含"re" 的行
$ awk '/re/ ' log.txt
---------------------------------------------
3 Are you like awk
10 There are orange,apple,mongo
12345
$ awk '/re/ ' log.txt
---------------------------------------------
3 Are you like awk
10 There are orange,apple,mongo
12345
忽略大小写:
$ awk 'BEGIN{IGNORECASE=1} /this/' log.txt
---------------------------------------------
2 this is a test
This's a test
1234
---------------------------------------------
2 this is a test
This's a test
1234
模式取反:
$ awk '$2 !~ /th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo
$ awk '!/th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo
12345678910
---------------------------------------------
Are like
a
There orange,apple,mongo
$ awk '!/th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo
12345678910
7、awk脚本
关于awk脚本,我们需要注意两个关键词BEGIN和END。
BEGIN{ 这里面放的是执行前的语句 }
END {这里面放的是处理完所有的行后要执行的语句 }
{这里面放的是处理每一行时要执行的语句}
假设有这么一个文件(学生成绩表):
BEGIN{ 这里面放的是执行前的语句 }
END {这里面放的是处理完所有的行后要执行的语句 }
{这里面放的是处理每一行时要执行的语句}
假设有这么一个文件(学生成绩表):
$ cat score.txt
Marry 2143 78 84 77
Jack 2321 66 78 45
Tom 2122 48 77 71
Mike 2537 87 97 95
Bob 2415 40 57 62
123456
Marry 2143 78 84 77
Jack 2321 66 78 45
Tom 2122 48 77 71
Mike 2537 87 97 95
Bob 2415 40 57 62
123456
awk脚本如下:
$ cat cal.awk
#!/bin/awk -f
#运行前
BEGIN {
math = 0
english = 0
computer = 0
#!/bin/awk -f
#运行前
BEGIN {
math = 0
english = 0
computer = 0
printf "NAME NO. MATH ENGLISH COMPUTER TOTAL\n"
printf "---------------------------------------------\n"
}
#运行中
{
math+=$3
english+=$4
computer+=$5
printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
printf "---------------------------------------------\n"
printf " TOTAL:%10d %8d %8d \n", math, english, computer
printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}
123456789101112131415161718192021222324
printf "---------------------------------------------\n"
}
#运行中
{
math+=$3
english+=$4
computer+=$5
printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
printf "---------------------------------------------\n"
printf " TOTAL:%10d %8d %8d \n", math, english, computer
printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}
123456789101112131415161718192021222324
运行结果:
$ awk -f cal.awk score.txt
NAME NO. MATH ENGLISH COMPUTER TOTAL
---------------------------------------------
Marry 2143 78 84 77 239
Jack 2321 66 78 45 189
Tom 2122 48 77 71 196
Mike 2537 87 97 95 279
Bob 2415 40 57 62 159
---------------------------------------------
TOTAL: 319 393 350
AVERAGE: 63.80 78.60 70.00
1234567891011
NAME NO. MATH ENGLISH COMPUTER TOTAL
---------------------------------------------
Marry 2143 78 84 77 239
Jack 2321 66 78 45 189
Tom 2122 48 77 71 196
Mike 2537 87 97 95 279
Bob 2415 40 57 62 159
---------------------------------------------
TOTAL: 319 393 350
AVERAGE: 63.80 78.60 70.00
1234567891011
8、一些其他实例:
计算文件大小:
$ ls -l *.txt | awk '{sum+=$6} END {print sum}'
--------------------------------------------------
666581
123
--------------------------------------------------
666581
123
从文件中找出长度大于80的行:
awk 'length>80' log.txt
1
1
打印九九乘法表:
seq 9 | sed 'H;g' | awk -v RS
————————————————
版权声明:本文为CSDN博主「yearing1017」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jin970505/article/details/79056457
————————————————
版权声明:本文为CSDN博主「yearing1017」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/jin970505/article/details/79056457
庖丁解牛awk
1.想要将下面文件中的域名提取出来,并且统计出现的次数。
[root@localhost ~]# cat hanjiali.txt 192.168.170.133 192.168.170.143 192.168.170.143 191.168.170.143 191.168.172.133 191.168.133.133 191.168.161.133 191.168.153.133 191.168.0.133 http://www.etiantion.org/index.html http://post.etiantion.org/index.html http://mp3.etiantion.org/index.html http://www.etiantion.org/3.html http://post.etiantion.org/2.html
解答:1.按照普通方式进行解答
[root@localhost ~]# awk -F "/" '/^h/{print $3}' hanjiali.txt|sort -rn|uniq -c 2 www.etiantion.org 2 post.etiantion.org 1 mp3.etiantion.org
awk -F "/" 把“/”看作分割符,将内容进行分割 '/^h/{print $3}' hanjiali.txt| 过滤出hanjiali.txt以h开头的第三部分内容 sort -rn| 排序:r 数值从大到小反向排序 n 数值大小排序 uniq -c 列出出现的次数
2.AWK数组方式进行解答
[root@localhost ~]# awk -F "/" '{++S[$3]} END {for (key in S) print S[key],key}' hanjiali.txt|sort -rn
10
2 www.etiantion.org
2 post.etiantion.org
1 mp3.etiantion.org
awk -F "/" 以“/”为分隔符,分割内容 '{++S[$3]} ++S 表示把某个数加1,就是将后面的S[..]状态连接数+1 ++S[$3] 表示把某个数加! END {for (key in S) 遍历数S[]组 print S[key],key}' S[key] 表示数组元素的值 打印数组的键和值 hanjiali.txt|sort -rn