文本三剑客--awk

是功能最强大的文本工具,也是按行进行操作,对行进行操作后,可以根据指定命令来对行取列,默认以 空格 或 tab键 作为分隔符作为分隔

基本格式

awk 选项  '模式或条件 {操作}'  文件1   文件2...

常用选项 :

-F :指定分隔符

-v(小v) :变量赋值

内置变量

内置变量,不能用双引号括起来,不然系统会把它当成字符串。
$0: 打印所有内容
$n: 处理行的第几列        例: $1表示第一列
NR: 当前处理的行的行号  只打印行号
NF: 当前处理的行的字段个数。$NF代表最后一个字段
FS: 列分割符。指定每行文本的字段分隔符, 和 -F 作用一致    -F:  =    FS=“ :”
OFS:  输出内容的列分隔符
RS:  指定分隔符为回车

基本打印用法:

awk   '{print}'   文件名    表示打印文件内容
​
awk   '0{print}'   1.txt      0表示不打印内容  ,1表示打印内容,默认为 1
​
awk   '{print NR}'   1.txt      表示打印行号,显示文件一共有几行
​
awk   '{print NR,$0}'   1.txt     表示输出行号,并且打印所有内容
​
awk   'NR==3{print}'   1.txt      表示指定打印出第3行的内容
​
awk   'NR==3,NR==5{print}'   1.txt    表示打印3-5行的内容
​
awk   'NR==3;NR==5{print}'   1.txt     表示打印3和5行

奇偶行打印:

awk   'NR%2==0{print}'  1.txt     表示打印偶数行

awk   'NR%2==1{print}'  1.txt     表示打印奇数行

awk运算:(支持小数运算)

awk   'BEGIN{print 100+200}' 

awk   'BEGIN{print 10.2+20.3}

awk   'BEGIN{print 2^3}'   结果为8

awk   'BEGIN{print 3**2}'   结果为9
^和**都是幂运算,表示次方

awk的内置函数:getline

  • 当getline左右无重定向符号 < , > 或者管道符号(“|”)时,
    awk首先读取的是第一行,而加上getline会跳过第一行 ,从第二行开始获取(2、4、6……)相当于偶数打印
awk '{getline;print}'  1.txt 
  • 当getline左右有管道符号或重定向符时,>表示覆盖 >>表示在尾行添加 
awk '{getline < "1.txt"; print > "2.txt";}' test1.txt  
   
#将1.txt文件内容输入到2.txt文件中 

管道符:

ls | awk '{getline data; print $0, data;}' 
结果为: 1. txt    2.txt
​
表示把ls的命令结果,输出给data(自定义变量)
data是变量 把ls的内容输出给变量,然后打印出结果,如果无内容,不做任何操作

文本内容匹配过滤打印:

awk  '/^root/{print}'  /etc/passwd    #打印passwd文件下以root开头的内容
 
awk  '/bash$/{print}'  /etc/passwd       #打印passwd文件下以bash结尾的内容 

BEGIN打印模式:

格式: awk 'BEGIN{...};{...};END{...}' 文件

  • 在awk处理指定的文本之前,需要先执行BEGIN{...}模式里的命令操作

  • 中间的{...} 是真正用于处理文件的命令操作

  • 在awk处理完文件后才会执行END{...}模式里的命令操作 ,一般都是打印命令结果

例: awk  'BEGIN{i=1};{i++};END{print i}' 1.txt  

#表示1.txt文件内容,从第一行开始,每次自加1,最终显示共有多少行 
     

对字段进行处理打印:

head -n5 /etc/passwd |awk  -F: '{print $1}'  

#查看passwd文件前5行,以“ :”为分割,打印第一列

awk条件判断打印:

awk -F: '$3>500{print $0}' /etc/passwd    #查看passwd文件,第三列大于500的打印所有
​
awk -F: '!($3>10){print $0}' /etc/passwd  #取反 查看passwd文件,第三列大于10的除外,打印其他所有

awk的精准筛选:

< ==: 用于对比数值

$n~"字符串" : 代表第n个字段包含某个字符串

$n!~"字符串" : 代表第n个字段不包含某个字符串

$n=="字符串" : 代表第n个字段就是某个字符串

$n!="字符串" : 代表第n个字段不是某个字符串

$NF: 表示最后一个字段

awk -F: '$7~"bash" {print $1,$NF}' /etc/passwd   
#passwd文件中第七个字段包含bash的,打印第一个字段和最后一个字段
   
awk -F: '$7!~"nologin" {print $1,$NF}' /etc/passwd
#passwd文件中第七个字段不包含nologin的,打印第一个字段和最后一个字段

awk的三元表达式:

格式:awk '(条件表达式)?(A表达式或者值):(B表达式或者值)'

awk -F: '{i=($3>$4)?$3:$4;{print i}}' /etc/passwd|sed -n '1,6p'

#比较passwd文件中以":"为分割的第三个和第四个字段的大小,

?和:  相当于if和else   表示为 if ($3 > $4) {i=$3 } else {i=$4 } 然后打印其中的1-6行;

awk结合数组运用:

awk 'BEGIN{a[0]=10;a[1]=20;a[2]=30;print a[1]}'  #定义数组,打印下标1的值
​
awk '{a[$1]++};END{for(i in a){print i,a[i]}}' 1.txt 
原理:a[$1]初始为0,a[$1]++后即为1,
awk会按行读取文件1..txt的内容,然后逐个单词存储到数组a中。
每个单词都作为数组a的索引,所以每个单词都对应一个值,初始值为0。
读取文件的第一行,单词为 aaa,此时a[aaa]为0,执行 a[$1]++ 后,a[aaa]变成1。
读取文件的第二行,单词为 aaa,此时a[aaa]为1,执行 a[$1]++ 后,a[aaa]变成2。
读取文件的第三行,单词为 bbb,此时a[bbb]为0,执行 a[$1]++ 后,a[bbb]变成1。
读取文件的第四行,单词为 ccc,此时a[ccc]为0,执行 a[$1]++ 后,a[ccc]变成1。
最终输出显示 :a[aaa]=2,a[bbb]=1,a[ccc]=1。
​

你可能感兴趣的:(linux,运维,服务器)