【原创】马哥 文本三剑客之awk
命令
awk
全称:
man搜索:
简述
基本用法
选项
用法与实验
-
print 打印
(1)(2)(3) -
变量
1、内建变量
FS与OFS
RS与ORS
NR与FNR
NF
ARGC与ARGC
2、自定义变量 -
printf
格式:
1、操作符
算数操作符
赋值符
比较操作符
模式匹配符
逻辑操作符
2、函数调用
3、条件表达式 -
PATTENR
5种模式:
(1)empty
(2)/regular expression/
(3)relational expression
(4)line ranges
(5)BEGIN/END模式 -
常用的action
-
控制语句
awk命令
全名:Aho,Weinberger,Kernighan
报告生成器,格式化文本输出,有遍历文本内容的能力。
man搜索:
gawk - pattern scanning and processing language
简述
基本用法:
gawk [options] 'program' FILE...
program:PATTERN{ACTION STATEMENTS}
* 语句之间用分号分隔
选项:
-F 指明输入时用到的字段分隔符
-v var=value: 自定义变量 (一个-v选项只定义一个变量)
(如awk -v FS=":")
用法与实验
-
print 打印
格式: print item1,item2, ...
要点:
1)逗号作分隔符 "," (命令默认用逗号代替空白字符)
有逗号分隔符和无逗号分隔符
如下图👇
2) 输出的个item可以 字符串,也可以是数值;当前记录的字段、变
量或awk的表达式;
3) 省略item,等于全部打印整行字符{print}
如下图👇
-
变量
1、内建变量
FS与OFS
RS与ORS
NR与FNR
NF
ARGC与ARGC
FS与OFS
FS:指明输入字段分隔符;默认为空白字符 input field seperator
OFS:指明输出字段分隔符;默认为空白字符 output field seperator
例: 只指明输入分隔符显示出的文本内容 如下图👇
小结:可以自定义显示要提取的文本内容中的分隔符,再没有指定的输出分隔符的前提下 输出分隔符默认为空白字符
RS与ORS
RS:输入时的换行符;
指明了要赋值给RS的字符 要执行的文本内容中的相应字符就会变成换
行符并将执行结果输出到屏幕上
如下图👇
ORS:输出时的换行符;
例:换行符为冒号的输出结果 如下图👇
输入换行符为冒号和输出换行符为"#"的结果
NR与FNR
NR:统计当前打开文件的行数;(注意:要区别{print NF}和{print $NF}的区别)
FNR:各文件分别计数,行数;
如下图👇
FILENAME
FILENAME:当前文件名;当前查看的文件内容所在文件的文件名
如下图👇
ARGC和ARGV
ARGC:命令行参数的个数;
ARGV: 数组,保存的时命令行所给定的各参数;
如下图👇
NF
字段数量 '{print NF}'
例:提取passwd文件中前七的内容对比
如下图👇
2、自定义变量
-v var=value 变量名区分字符大小写
awk -v test='hello gawk' '{print test}' /etc/fstab
将文本的每行内容都替换成已赋值变量并输出到屏幕上
如下图👇
在program直接定义
例:
两种方法👇 (加入 'BEGIN' 使程序只执行一次的结果)
# awk -v test='hello gawk' 'BEGIN{print test}'
# awk 'BEGIN {test="hello gawk";print test}'
执行后如图:
-
printf 格式化输出命令
格式: printf FORMAT,item1,item2,..... (1)FORMAT; (2)不会自动换行,需要显示给出换行控制符,\n (3)FORMAT中需要分别为后面的每个item指定一个格式化符号; 格式符: %c:显示字符的ASCII码; %d ,%i:显示十进制整数; %e,%E:科学计数法数值显示; %f:显示为浮点数; %g,%G:以科学计数法或浮点形式显示数值; %s:显示字符串; %u:无符号整数; %%:显示%自身;
例1:
格式符%s的用法 如: # awk -F: '{printf "%s",$1}' /etc/passwd (执行后如下图)👇
因为输出显示的内容没有换行,所以要显示换行可以在格式化符号后面加\n
如:
# awk -F: '{printf "%s\n",$1}' /etc/passwd (执行效果如下图)👇
例2:
扩展使用
如:
# awk -F: '{printf "Username: %s\n",$1}' /etc/passwd
# awk -F: '{printf "Username: %s, UID: %d\n",$1,$3}' /etc/passwd
装饰符:
#[.#]: 第一个数字控制显示的宽度;第二个#表示小数点后的精度;
使用方法:%3.1f
- : 左对齐
使用方法:%-3f
+:显示数值的符号
-
操作符
算数操作符
x+y,x-y,x*y,x/y,x^y,x%y -x: +x:
赋值符
+=,-=,*=,/=,%=,^= ++ --
比较操作符
>, >=, <, <=, != ==
模式匹配符
~:是否匹配 !~:是否不匹配
逻辑操作符
短路与 && 短路或 || !
函数调用
语句格式: function_name(argu1,argue2,....)
条件表达式:
语句格式: '{selector?if-ture-expression:if-false-expression}' 例:👇 # awk -F: '{$3>=1000?usertype="Common User":usertype="Sysadmin or SysUser";printf "%15s:%-s\n",$1,usertype}' /etc/passwd
-
PATTERN
(1)empty:空模式,匹配每一行;
(2)/regular expression/:仅处理能够被此处的模式匹配到的行;
实例:
👇 # awk '/^UUID/{print $1}' /etc/fstab
加!对文本内容取反:
👇 # awk '!/^UUID/{print $1}' /etc/fstab
(3)relational expression:关系表达式;
结果有“真”有“假”;结果为“真”才会被处理; (真:结果为非0值,非空字符串)
如:(大于和小于的关系表达对比下图👇)
# awk -F:'$3>=1000{print $1,$3}' /etc/passwd 👉(指定大于或等于设定值的表达)
# awk -F:'$3<1000{print $1,$3}' /etc/passwd 👉(指定小于或等于设定值的表达)
两种匹配模式👇
# awk -F: '$NF~/bash$/{print $1,$NF}' /etc/passwd 👉 正则表达式匹配
# awk -F: '$NF=="/bin/bash"{print $1,$NF}' /etc/passwd 👉 赋值匹配
(4)line ranges:行范围
语句格式:(注意:不支持直接给出数字的格式)
startline,endline:
👉 /part1/,/part2/
例: 对行号进行变量赋值
# awk -F: '(NR>=2&&NR<=10){print $1}' /etc/passwd (执行后如图👇)
(5)BEGIN/END模式:
BEGIN{ } : 仅在开始处理文件中的文本之前执行一次;
END{ } :尽在文本处理完成之后执行一次;
实验一:打印一个表头
# awk -F: 'BEGIN{print " username uid \n-------------------"}'
执行后如下图👇
实验二: 显示表头和文本内容
# awk -F: 'BEGIN{print " username uid \n----------------\
---"};{print $1,$3}' /etc/passwd
执行后如图👇
实验三: 表头内容表尾
# awk -F: 'BEGIN{print" username uid \n--------------\
-----"};{print $1,$3}END{print "===============\n end "}' /etc/passwd
执行后如图👇
实验四: 使用printf命令
# awk -F: 'BEGIN{print"username uid \n====================\
=="}{printf"%-19s %d\n", $1,$3}END{print "=======================\nend"}' /etc/passwd
执行后如图👇
-
常用的action
(1)Expressions
(2)Control statements:if,while等;
(3)Compound statements:组合语句;
(4)input statements
(5)output statements -
控制语句
if(condition){statments} if(condition){statments}else{statements} while(conditon){statments} do {statments} while(condition) for(exper1;exper2;exper3){statements} break continue delete array[index] delete array exit {statments}