awk 可以截取文档中的某段
awk -F':' '{print $2}' 工作中最常用的指令
-F 指定源文档的分隔符,默认为空格
#awk '{print $2}' 1.txt 【默认空格分隔符,打印第二段】
#awk -F ':' '{print $1}' 1.txt 【打印第一段】
# awk -F ':' '{print $4,$7}' 1.txt |head -n2 【打印第四段 和
第七段】
0 /bin/bash
1 /sbin/nologin
# awk -F ':' '{print $7,$4}' 1.txt |head -n2 【打印第七段 和 第四段】
/bin/bash 0
/sbin/nologin 1
{OFS="#"} 内部变量自定义显示结果中的分隔符
# awk -F ':' '{print $4"#"$7}' 1.txt |head -n2
0#/bin/bash
1#/sbin/nologin
# awk -F ':' '{OFS="#"}''{print $4,$7}' 1.txt |head -n2
# awk -F ':' '{OFS="#"}{print $4,$7}' 1.txt |head -n2 一个分号也可以
0#/bin/bash
1#/sbin/nologin
#awk -F ':' '{print $1"#"$2"#"$3"#"$4}' 1.txt
以#链接每个段
#awk -F ':' '{OFS="#"} {print$1,$2,$3,$4}' 1.txt 一个分号
OFS 表示内部变量
匹配包含字符或字符串的行
#awk '/oo/' 1.txt
#awk '/root|nolog/' 1.txt
包含root或者nolog的行
#awk '/r*o/' 1.txt 包含 r*o 的行
#awk '/r.*o/' 1.txt 包含 r.*o 的行
# awk '/(oo)+/' 1.txt 包含 (oo) 的行
# awk '/^(root)/' 1.txt 以root开头的行
#awk -F ':" '/(bash)$/' 1.txt 以bash 结尾的行
正则表达式中,有一个用法就是一个字符或者一串字符的重复次数。比如(abc){1,3}
表示含有 abc abcabc abcabcabc 这样的行都会匹配到
awk 直接这样用是匹配不到东西的
awk '/(abc){1,3}/' 1.txt
这是因为在awk中()和{}都有特殊的含义,需要做个特殊处理才可以:
awk --posix '/(abc){1,3}/' 1.txt
针对某个段匹配
#awk -F ':' '$1 ~/oo/' 1.txt 【匹配第一段出现oo的行】
# awk -F ':' '$1~/r*o/' 1.txt 【匹配第一段出现r*o的行】
root:x:0:0:root:/root:/bin/bash
daemon:x:2:2:daemon:/sbin:/sbin/nologin
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
operator:x:11:0:operator:/root:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
# awk -F ':' '$1~/r*o/ {print $3}' 1.txt 【匹配第一段包含r*o的行,并且列出第三段】
0
2
6
11
13
99
89
多次匹配 ; ;表示匹配前后各一次并且打印结果
#awk -F ':' '$1~/nobody/;$4~/89/' 1.txt 【匹配第一段出现nobody,第四段出现89的行】
nobody:x:99:99:Nobody:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
# awk -F ':' '$1~/r*o/ {print $1,$3}; $1~/nobody/ {print $1,$3}' 1.txt
root 0
daemon 2
shutdown 6
operator 11
gopher 13
nobody 99 【此处两个nobody 99,是因为第一个r*o匹配了o,第二个nobody匹配】
nobody 99
postfix 89
单次匹配 |
# awk -F ':' '$1~/r*t|nobody/ {print $1,$3}' 1.txt 【匹配第一段包含r*t或者nobody的行】
root 0
daemon 2
shutdown 6
operator 11
gopher 13
nobody 99
postfix 89
awk '/user|root/' 1.txt是匹配user或者root。如果是user并且root呢?用什么符号?
awk '$0 ~ /user/ && $0 ~ /root/' 1.txt 【$0表示匹配整行】
下面的例子是自己做的实验,如有不对请指正
awk '$1 ~ /user/ && $1 ~ /root/' 1.txt 【匹配第一段含有user并且第一段含有root的行,这里没有指定分隔符,所以整行应该都看成了第一段,没有符合条件的行】【打印既有root,又有user的行】
awk '$1 ~ /user/ || $1 ~ /root/' 1.txt 【匹配第一段含有user 或者 第一段含有root的行,没有指定分隔符,所以整行都看成了第一段。】
awk '$1 ~ /nologin/ && $1 ~ /root/' 1.txt 【没有指定分隔符,会匹配含有nologin和root的所有的行】
awk -F ':' '$1 ~ /root/ && $1 ~ /bin/' 1.txt 【指定:分隔符,匹配第一段出现root并且第一段出现bin的行,并没有这样的行,所以没有返回结果】
awk -F ':' '$1~/root/ || $1~/bin/' 1.txt 【指定:分隔符,匹配第一段出现root 或者 第一段出现 bin的行。】
awk -F ':' '$1 ~ /root/ && $2 ~ /x/' 1.txt 【指定:分隔符,第一段是root,第二段是x的行,返回结果如下】
root:x:0:0:root:/root:/bin/bash
条件操作符 ==,>,<,!=,>=,<=
== 完全等于
#awk -F ':' '$3==0' 1.txt 【匹配第三段为0的行并打印整行】
#awk -F ':' '$1=="root"' 1.txt 【匹配第一段为root的行并打印整行】
#awk -F ':' '$1=="root" || $7~ /nolog/' 1.txt 【匹配第一段为root或者第七段包含nolog的行并打印】【等号后面跟字母一定是“”,不能是斜杠或者其他符合】
>= 大于等于
#awk -F ':' '$3>=500' 1.txt 【第三段大于等于500】
当比较数字时,不能加双引号,如果写成 $3>="500" ,便会按照编码排序,不符合数字排序逻辑。
!= 不等于
#awk -F ':' '$7!="/bin/nologin"' 1.txt 【第七段不是 '/sbin/nologin'】【nologin的后面无需/】
#awk -F ':' "$7!~/nologin/" 1.txt 【匹配第七段不包含nologin】【nolog后面需要/】
< 小于
#awk -F ':' '$3<$4' 1.txt 【第三段小于第四段】
#awk -F '$3>5 && $3<7' 1.txt 【第三段大于5,并且第三段小于7】
#awk -F '$3>5 || $7=="/bin/bash"' 1.txt 【第三段大于5
或者第七段为 '/bin/bash' 】
awk 内置变量 NF(段数) NR(行数)
#head -n3 1.txt |awk -F ':' '{print NF}' 【打印1.txt前三行的段落数量,以:分段】
#head -n3 1.txt |awk -F ':' '{print $NF}' 【打印1.txt的前三行的最后一段】
#haed -n3 1.txt |awk -F ':' '{print NR}' 【打印前三行的行数】没意义
NR number of Row
#awk -F ':' '{print $NR} 1.txt 【打印第N行的第N段,第一行第一段,第二行第二段...】
#awk -F ':' 'NR<10' 1.txt 【number of Row 打印小于10行的行,打印前9行】
#awk 'NR>20' 1.txt 【打印大于20的行】
#awk 'NR==10' 1.txt 【打印第十行,一定是两个等号】
#awk -F ':' 'NR==10 {print $1, $7}' 1.txt 【打印第十行的第一段和第七段】
#awk -F ':' 'OFS=":" {if (NR==10) print $1, $7}' 1.txt
#awk -F ':' 'NR>15 && $1 ~/ssh/' 1.txt
【打印15行以后并且第一段包含'ssh'的行】
# awk -F ':' 'NR>5 && NR<10 {print $1,$7}' 1.txt
【打印5-10行之间的第一段和第七段】
NF number of
#awk '{print NF}" 1.txt 【默认空格为分隔符,实际是:,那么每行的段落数量都是1】
# awk -F ':' '{print $NF}' 1.txt 【以 : 为分隔符,打印每一行的行尾】
#awk -F ':' '{print NF}' 1.txt 【以:为分隔符,打印每一行的段落数量】
#awk -F ':' '{if (NF=7) print $1}' 1.txt
【如果段数=7,那么打印第一段】实验不对。不对的原因是NF==7,两个等号
更改某个段的值
#awk -F ':' '$1="root"' 1.txt 【把第一段全部改为root】
#awk -F ':' '{OFS="@"} $1="root"' 1.txt 【第一段全部改为root,并且以@为分隔符】
数学计算
# awk -F ':' '$7=$3+$4' 1.txt 【把第三段和第四段值相加,并赋予第七段】
#awk -F ':' '{$7=$3+$4;print $0}' 1.txt
这样相当于改变了原来的文本结构,所以print$0的时候就不再有分隔符显示。如果想显示分隔符需要借助OFS
#awk -F ':' '{OFS=":"} {$7=$3+$4;print $1}' 1.txt
【第七段等于第三+第四,并且打印第一段,以:为分隔符】
#awk -F ':' 'OFS=":" {$7=$3+$4;print $1,$3}' 1.txt
【第七段等于第三段+第四段,并且打印第一段和第三段,以:为分隔符】
测试上述的情况,打印$0
循环变量 计算第三段的总和
#awk -F ':' '{(tot=tot+$3)}; END {print tot}' 1.txt
awk 中也可以使用if关键词
#awk -F ':' '{if ($1=="root") print $0}' 1.txt
awk -F':' 'BEGIN {print "start!";OFS= "#"} {if($3>100) {$8=$3+$4; print $0}} END {print "end!"}' 1.txt
注意和下面的比较,此处涉及OFS和$0的联系。
awk -F':' 'BEGIN {print "start!";OFS= "#"} {if($3>100) {print $0}} END {print "end!"}' 1.txt
awk -F':' 'BEGIN {print "start!";OFS= "#"} {if($3>100) {print $1,$3}} END {print "end!"}' 1.txt
如果打印的时候打印的是$0,那么OFS并不会起作用,如果打印的结构发生变化,OFS内部变量才会起作用。
#awk -F ':' '$1~/root|mail/' 1.txt 【第一段包含root或者mail的行】
#awk -F ':' '$1~/root/ || $7~/bash/' 1.txt 【第一段包含root,或者第七段包含bash的行】
#awk -F '$3>5 || $7=="/bin/bash"' 1.txt 【第三段大于5
或者第七段为 '/bin/bash' 】
#awk -F '$3>5 && $3<7' 1.txt 【第三段大于5,并且第三段小于7】
#awk -F ':' '$1 ~ /root/ && $2 ~ /x/' 1.txt 【第一段包含root并且第二段包含x的行】
tcp连接状态的统计,或者IP统计
面试考点
# netstat -an |awk '/^tcp/ {s[$6]++}; END {for (a in s) print a, s[a]}'
$6定义一个变量内容,代表$6的值或内容,后面的a就代表$6实际的变量内容
s 代表一个变量,内容是 $6 里面的不同的行,s[a]代表统计变量结果,a in s 声明变量内容和变量
S1=S1+1
s 和 a 可以随便替换,保证格式正确即可。
# netstat -an |awk '/^tcp/ {M[$6]++}; END {for (b in M) print b, M[b]}'
asdfa S1=S(asdfa) =1
asdfa S1=2
bbbb S2=1
bbaa S2=2
cc S3=1
asdfa S1=3
本文详细介绍了Linux中awk命令的使用,包括字段分隔符、打印特定字段、自定义分隔符、正则表达式匹配以及条件判断等操作。通过实例展示了awk在处理文本文件时的强大功能,例如查找、替换和统计特定行。
3108

被折叠的 条评论
为什么被折叠?



