One, awk
1.1 Working principle:
Read text line by line, separated by space or tab by default, save the separated fields to built-in variables, and execute editing commands according to the mode or condition.
1.2 The difference between sed and awk
The sed command is often used to process a whole line, while awk tends to divide a line into multiple fields and then process it. The reading of awk information is also read line by line, and the execution result can be printed and displayed through the print function. In the process of using the awk command, you can use the logical operators "&" to mean "and", "||" to mean "or", "!" to mean "not", and you can also perform simple mathematical operations, such as +,- , *, /, %, ^ represent addition, subtraction, multiplication, division, remainder and power respectively.
1.3 Command format
awk 选项 '模式或条件{操作}' 文件1 文件2...
awk -f 脚本文件 文件1 文件2...
The common built-in variables of awk (can be used directly) are as follows
FS:列分割符。指定每行文本的字段分隔符,默认为空格或制表位。与"-F"作用相同
NF:当前处理的行的字段个数
NR:当前处理的行的行号(序数)。
$0:当前处理的行的整行内容,
$n:当前处理行的第n个字段(第n列)
FILENAME:被处理的文件名。
RS:行分隔符。awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录,而awk一次仅读入一条记录,以进行处理。预设值是'\n'
Output text by line:
awk '{print}' sed.txt 输出文件所有内容
awk '{print $0}' sed.txt 输出文件所有内容
awk 'NR==1,NR==3{print}' sed.txt 输出第1~3行的内容
awk '(NR>=1)&&(NR<=3){print}' sed.txt 输出第1~3行的内容
awk 'NR==1||NR==3{print}' sed.txt 输出第一行、第三行的内容
awk '(NR%2)==1{print}' sed.txt 输出所有奇数行的内容
awk '(NR%2)==o{print}' sed.txt 输出所有偶数行的内容
awk '/^root/{print}' /etc/passwd 输出以root开头的行
awk '/nologin$/{print}' /etc/passwd 输出以nologin结尾的行
awk 'BEGIN {x=0};/\/bin\/bash$/{x++};END {print x}' /etc/passwd 统计以/bin/bash结尾的行数
BEGIN mode means that before processing the specified text, you need to perform the specified action in BEGIN mode, then awk processes the specified text, and then executes the specified action in END. In the END{} statement, statements such as print results are often put in
awk -F ":" '{print $1,$3}' /etc/passwd 以:为分割,输出每行第1个、第3个字段
awk -F ":" '$3<5{print $1,$3}' /etc/passwd 输出第3个字段小于5的每行第1个、第3个字段
$3<5 第3个字段要小于5
awk -F ":" '!($3<200){print}' /etc/passwd 输出第3个字段不小于200的行
awk 'BEGIN {FS=":"};{if($3>=200){print}}' /etc/passwd 先处理完BEGIN的内容,再打印结果
awk -F ":" '{max=($3>$4)?$3:$4;{print max}}' /etc//passwd
($3>$4)?$3:$4三元运算符,如果第3个字段的值大于第4个字段的值,则把第3个字段的值赋给max,否则第4个字段的值赋给max
awk -F ":" '{print NR,$0}' /etc/passwd 输出每行内容和行号,每输出一行记录,NR值加1
awk -F ":" '$7~"/bash"{print$1}' /etc/passwd 输出以冒号为分割第七个字段包含/bash的第1个字段
awk -F ":" '($1~"root")&&(NF==7){print $1,$2}' /etc/passwd
以冒号为分割,第1个字段包含root且有7个字段的行,输出第1个、第2个字段
awk -F ":" '($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' /etc/passwd
输出第7个字段既不包含/bin/bash也不包含/sbin/bash的所有行
Invoke shell commands through pipe symbols and double quotes
echo $PATH | awk 'BEGIN{RS=":"};END{print NR}'
统计以冒号分割的文本的字符段落数,END{
}语句块中,往往会放入打印结果等
awk -F ":" '/bash$/{print | "wc -l"}' /etc/passwd
调用 wc -l 命令统计使用 bash 的用户个数,等同于 grep -c "bash$" /etc/passwd
以冒号为分割打印结尾字包含bash的行然后显示行数总数
free -m |awk '/Mem:/ {print int($3/($3+$4)*100)"%"}' 查看当前内存使用百分比
top -b -n 1 | grep Cpu |awk -F ',' '{print $4}' | awk '{print $1}' 查看当前cpu空闲率,(-b -n 1 表示只需要1次的输出结果)
date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H:%M:%S"
显示上次系统重启时间,等同于uptime;second ago为显示多少秒前的时间,+"%F %H:%M:%S"等同于 +"%Y-%m-%d%H:%M:%S"的时间格式
awk 'BEGIN {n=0;while ("w" | getline) n++ ; {print n-2}"%"}' 调用w命令,并用来统计在线用户数
awk 'BEGIN {while ("w" | getline) n++ ; {print n-2}"%"}'
awk 'BEGIN {"hostname" | getline ; {print $0}}' 调用 hostname,并输出当前的主机名
当getline左右无重定向符“<”或“|”时,getline作用于当前文件,读入当前文件的第一行给其后跟的变量var或$0;应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到的返回结果是隔行的。
当getline左右有重定向符“<”或“|”时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。
seq 10 | awk '{print $0; getline}'
seq 10 | awk '{getline; print $0}'