安全渗透——AWK知识整理

1.awk的定义

awk是一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入(stdin)、一个或多个文件,或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk有很多内建的功能,比如数组、函数等,这是它和C语言的相同之处,灵活性是awk最大的优势。
 

2.awk的使用方法

2.1 awk的语法

awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file

2.2 awk的命令常用选项

变量:内置和自

-F fs:fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:
-v var=value:赋值一个用户定义变量,将外部变量传递给awk
-f scripfile:从脚本文件中读取awk命令
-m[fr] val:对val值设置内在限制,-mf选项限制分配给val的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用

3.awk变量

定义变量,每个变量前加 -v 命令选项

3.1 内置变量  

(1)格式

FS :输入字段分隔符,默认为空白字符
OFS :输出字段分隔符,默认为空白字符
RS :输入记录分隔符,指定输入时的换行符,原换行符仍有效
ORS :输出记录分隔符,输出时用指定符号代替换行符
NF :字段数量,共有多少字段, NF引用最后一列,(NF-1)引用倒数第2列
NR :行号,后可跟多个文件,第二个文件行号继续从第一个文件最后行号开始
FNR :各文件分别计数, 行号,后跟一个文件和NR一样,跟多个文件,第二个文件行号从1开始
FILENAME :当前文件名
ARGC :命令行参数的个数
ARGV :数组,保存的是命令行所给定的各参数,查看参数
 

[root@along ~]# cat awkdemo
hello:world
linux:redhat:lalala:hahaha
along:love:youou
[root@along ~]# awk -v FS=':' '{print $1,$2}' awkdemo  #FS指定输入分隔符
hello world
linux redhat
along love
[root@along ~]# awk -v FS=':' -v OFS='---' '{print $1,$2}' awkdemo  #OFS指定输出分隔符
hello---world
linux---redhat
along---love
[root@along ~]# awk -v RS=':' '{print $1,$2}' awkdemo
hello
world linux
redhat
lalala
hahaha along
love
you
[root@along ~]# awk -v FS=':' -v ORS='---' '{print $1,$2}' awkdemo
hello world---linux redhat---along love---
[root@along ~]# awk -F: '{print NF}' awkdemo
2
4
3
[root@along ~]# awk -F: '{print $(NF-1)}' awkdemo  #显示倒数第2列
hello
lalala
love
[root@along ~]# awk '{print NR}' awkdemo awkdemo1
1
2
3
4
5
[root@along ~]# awk END'{print NR}' awkdemo awkdemo1
5
[root@along ~]# awk '{print FNR}' awkdemo awkdemo1
1
2
3
1
2
[root@along ~]# awk '{print FILENAME}' awkdemo
awkdemo
awkdemo
awkdemo
[root@along ~]# awk 'BEGIN {print ARGC}' awkdemo awkdemo1
3
[root@along ~]# awk 'BEGIN {print ARGV[0]}' awkdemo awkdemo1
awk
[root@along ~]# awk 'BEGIN {print ARGV[1]}' awkdemo awkdemo1
awkdemo
[root@along ~]# awk 'BEGIN {print ARGV[2]}' awkdemo awkdemo1
awkdemo1

3.2 自定义变量

自定义变量( 区分字符大小写)

(1)-v var=value

① 先定义变量,后执行动作print

[root@along ~]# awk -v name="along" -F: '{print name":"$0}' awkdemo
along:hello:world
along:linux:redhat:lalala:hahaha
along:along:love:you

② 在执行动作print后定义变量

[root@along ~]# awk -F: '{print name":"$0;name="along"}' awkdemo
:hello:world
along:linux:redhat:lalala:hahaha
along:along:love:you

2)在program 中直接定义

可以把执行的动作放在脚本中,直接调用脚本 -f

[root@along ~]# cat awk.txt
{name="along";print name,$1}
[root@along ~]# awk -F: -f awk.txt awkdemo
along hello
along linux
along along

4.操作符

格式

  • 算术操作符:
    x+y, x-y, x*y, x/y, x^y, x%y
    -x:  转along"; print为数值
    
  • 字符串操作符:没有符号的操作符,字符串连接

  • 赋值操作符:

    =, +=, -=, *=, /=, %=, ^=
    ++a, --a
    
  • 比较操作符:
    ==, !=, >, >=, <, <=
    
  • 模式匹配符:
    ~ :左边是否和右边匹配包含 
    !~ :是否不匹配`
    
  • 逻辑操作符:
    与&& ,或|| ,非!
    
  • 函数调用:
    function_name(argu1, argu2, ...)
    
  • 条件表达式(三目表达式):
      selector
    
      ?
    
      if-true-expression
    
      :
    
      if-false-expression
    

5.awk控制语句

5.1 if-else判断

(1)语法

if(condition){statement;…}[else statement]  双分支
if(condition1){statement1}else if(condition2){statement2}else{statement3}  多分支

(2)使用场景:对awk 取得的整行或某个字段做条件判断

[root@along ~]# awk -F: '{if($3>10 && $3<1000)print $1,$3}' /etc/passwd
operator 11
games 1
[root@along ~]# awk -F: '{if($NF=="/bin/bash") print $1,$NF}' /etc/passwd
root /bin/bash
along /bin/bash
---输出总列数大于3的行
[root@along ~]# awk -F: '{if(NF>2) print $0}' awkdemo
linux:redhat:lalala:hahaha
along:love:you
---第3列>=1000为Common user,反之是root or Sysuser
[root@along ~]# awk -F: '{if($3>=1000) {printf "Common user: %s\n",$1} else{printf "root or Sysuser: %s\n",$1}}' /etc/passwd
root or Sysuser: root
root or Sysuser: bin
Common user: along
---磁盘利用率超过40的设备名和利用率
[root@along ~]# df -h|awk -F% '/^\/dev/{print $1}'|awk '$NF > 40{print $1,$NF}'
/dev/mapper/cl-root 43
---test=100和>90为very good; 90>test>60为good; test<60为no pass
[root@along ~]# awk 'BEGIN{ test=100;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}'
very good
[root@along ~]# awk 'BEGIN{ test=80;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}'
good
[root@along ~]# awk 'BEGIN{ test=50;if(test>90){print "very good"}else if(test>60){ print "good"}else{print "no pass"}}'
no pass

5.2 循环语句

5.2.1 while循环

while``(condition){statement;…}

使用场景

对一行内的多个字段逐一类似处理时使用

对数组中的各元素逐一处理时使用

---以along开头的行,以:为分隔,显示每一行的每个单词和其长度
[root@along ~]# awk -F: '/^along/{i=1;while(i<=NF){print $i,length($i); i++}}' awkdemo
along 5
love 4
you 3
---以:为分隔,显示每一行的长度大于6的单词和其长度
[root@along ~]# awk -F: '{i=1;while(i<=NF) {if(length($i)>=6){print $i,length($i)}; i++}}' awkdemo
redhat 6
lalala 6
hahaha 6
---计算1+2+3+...+100=5050
[root@along ~]# awk 'BEGIN{i=1;sum=0;while(i<=100){sum+=i;i++};print sum}'
5050

5.2.2 do-while循环

do` `{statement;…}``while``(condition)

意义:无论真假,至少执行一次循环体        

6.awk数组

6.1 关联数组:array[index-expression]

(1)可使用任意字符串;字符串要使用双引号括起来

(2)如果某数组元素事先不存在,在引用时,awk 会自动创建此元素,并将其值初始化为“空串”

(3)若要判断数组中是否存在某元素,要使用“index in array”格式进行遍历

(4)若要遍历数组中的每个元素,要使用for 循环**:for(var in array)** {for-body}
 

[root@along ~]# cat awkdemo2
aaa
bbbb
aaa
123
123
123
---去除重复的行
[root@along ~]# awk '!arr[$0]++' awkdemo2
aaa
bbbb
123
---打印文件内容,和该行重复第几次出现  取反不会影响数组中的值 只有在++得时候,值才会改变 ?
[root@along ~]# awk '{!arr[$0]++;print $0,arr[$0]}' awkdemo2
aaa 1 
bbbb 1
aaa 2
123 1
123 2
123 3

awk是AWK的命令行工具,它接受一个AWK脚本作为参数,并对输入进行处理。

花括号{}内是AWK脚本的主体,它定义了处理输入数据的操作。

!arr[$0]++:这是一个表达式,它使用了AWK中的数组arr来记录每一行的出现次数。在AWK中,$0表示当前行的全部内容。arr[$0]表示以当前行内容为索引的数组元素。!是逻辑取反操作符,将0转换为1,非0值转换为0。arr[$0]++表示将当前行内容为索引的数组元素自增1,然后返回旧值。所以!arr[$0]++在第一次遇到某一行时为真(1),而后续再次遇到该行时为假(0)。

print $0,arr[$0]:这是一个打印语句,用于输出当前行内容$0以及该行内容在数组中出现的次数arr[$0]。在AWK中,$0表示当前行的全部内容,arr[$0]表示数组中以当前行内容为索引的元素的值。

所以,这段代码的作用是读取文件"awkdemo2",对每一行进行处理,并输出每行内容及其在文件中出现的次数。如果文件中有多个相同的行,则会在输出中显示它们的重复次数

分析:把每行作为下标,第一次进来,相当于print ias…一样结果为空,打印空,!取反结果为1,打印本行,并且++变为不空,下次进来相同的行就是相同的下标,本来上次的值,!取反为空,不打印,++变为不空,所以每次重复进来的行都不打印

awk 关联数组 key=>value 无序

[root@along ~]# awk 'BEGIN{abc["ceo"]="along";abc["coo"]="mayun";abc["cto"]="mahuateng";for(i in abc){print i,abc[i]}}'
coo mayun
ceo along
cto mahuateng
[root@along ~]# awk '{for(i=1;i<=NF;i++)abc[$i]++}END{for(j in abc)print j,abc[j]}' awkdemo2
aaa 2
bbbb 1
123 3

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