第四节 awk数组和函数

一、数组 array

1.数组简介

简单来说:数组是存的一组数,将一组相关数据按照一定的顺序存放在一起

一般用于从记录中收集信息、统计次数、记录某个模式出现的次数等等。

2.创建数组

数组名[数组下标]=值

arr1[1]="a"

arr1[2]="b"

awk中,数组下标既可以是数字、也可以是变量、还可以是字符串(字符串必须加双引号)

注意:数组下标如果是数字:从1开始,而c语言是从0开始

数组可以定义后再使用,也可以直接使用。

3.删除单个键值(数组元素):

delete ARRAY[INDEX]

# awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";delete tB["a"];for(k in tB){print k,tB[k];}}'
b b1

4.删除整个数组:

方法 1:
for   (VAR  in  ARRAY)
delete  ARRAY[VAR]

方法 2: 该方法 gawk (gnu awk)专用,可移植性差,但效率是方法 1 的 3 倍左右
delete  ARRAY

5.数组和变量命名空间:

awk 的数组和变量用的是同一个地址空间,数组的名字和变量名不能重名。

即使数组被删除了也不能将名字用于变量命名,如以下的命令会报错:

a[1]=3; delete a ;a=3

6.数组的遍历:

用循环去遍历数组元素

for  (数组下标   in   数组名){  ...  }

for (i  in  ip)    i--代表下标


例题:1.  awk  'BEGIN{ip["127.0.0.1"]=1;ip["192.168.1.1"]=2;for (i  in ip){print i, ip[i] } }'

            2.  awk  '{ip[s1++;]}'

7.数组下标的两种类型:

(1)使用数值做下标

arr[1]    arr[3]    arr[x++]     arr[NR]

#awk  '{arr[x++]=$1};END{for  (i=NR-1;i>0;i--){print  i,arr [i] } }'  /etc/passwd

# awk '{arr[NR]=$1};END{for (i=NR;i>0;i--){print i,arr[i]}}' employees

(2)使用字符串做下标

# awk '{ip[$1]++}END{for (i in ip) {print i,ip[i]}}' /var/log/httpd/access_log

# awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log |sort -nr -t " " -k 2 | head


重点例题:

统计/etc/passwd中最后一行每一种shell出现的次数

awk  -F:  '{shells[$NF]++} END{for (i in  shells){print i ,shell[i]}}'  /etc/passwd

网站访问状态统计

netstat  -ant | grep ':80'|awk '{status[$NF]++}END{for (i  in status) {print  i , status[i] } }' |sort -k2  -n 

统计访问网站最高的IP的前五个

ss -ant |grep ':80' |awk -F":" '!/LISTEN/{ips[$(NF-1)]++}EDN{for (i  in  ips){print  i ,ips[i]}}' |sort -k2  -rn |head  -5

注:sort 排序
-n 按数字排序
-r 倒序
-t 指定分隔符
-k 第几列 排序键


#cat /etc/passwd | sort

8.数组相关函数

得到数组的长度

length(数组名称)

# awk 'BEGIN{a[1]=8;a[2]=9;print length(a)}'

二、函数

1.内置函数

1)大小写转换函数

toupper() 小写变大写
tolower() 大写变小写
# awk '{print toupper($1)}' score
# awk '{print tolower($1)}' datafile3

2.自定义函数

自定义函数(功能函数) function
格式:
函数名 (参数) { //参数是可选的
函数体;
返回值;
}

(1)自定义一个函数

# awk 'function over() {print "class is over"} {over()}' a  class is over


(2)函数的调用: 函数名(参数)

over()


(3)$? 返回0表示正确 非0错误






### awk 函数的详细信息及用法 #### 1. `length` 函数 `length` 是一个常见的字符串处理函数,用于计算字符串的字符数。它可以直接作用于字段或者整个记录。 示例代码如下: ```bash echo "Hello, World!" | awk '{print length($0)}' ``` 此代码会输出字符串 `"Hello, World!"` 的总长度,即 13[^1]。 --- #### 2. `split` 函数 `split` 函数可以将一个字符串按照指定的分隔符分割成多个部分,并存储在一个数组中。其语法为: ```awk split(string, array, separator) ``` 其中: - `string`: 被分割的原始字符串。 - `array`: 存储分割后的子串的数组。 - `separator`: 分割依据的分隔符。 示例代码如下: ```bash awk 'BEGIN { str = "cul-de-sac"; split(str, a, "-"); for (i in a) print i, a[i] }' ``` 这段代码会将字符串 `"cul-de-sac"` 按照 `-` 进行分割,并打印出索引对应的值[^4]。 --- #### 3. `isarray` 函数 `isarray` 函数用来判断给定的对象是否是一个数组。如果对象是数组,则返回 `1`;否则返回 `0`。 示例代码如下: ```bash awk 'BEGIN { str = "cul-de-sac"; split(str, a, "-"); print isarray(a) }' ``` 该代码会输出 `1`,因为变量 `a` 是通过 `split` 创建的一个数组[^3]。 --- #### 4. 字符串拼接与多行字符串处理 可以通过简单的赋值方式实现字符串拼接。对于多行字符串,可利用 `\n` 来表示换行符。 示例代码如下: ```bash echo "" | awk '{arrStr="hello\nworld"; split(arrStr, arr, "\n"); for (k in arr) print k, arr[k]}' ``` 这里定义了一个包含两行文字的字符串 `arrStr`,并通过 `split` 将其按换行符分开存入数组 `arr` 中。 --- #### 参数说明 ##### (1)内置参数 | 参数名 | 描述 | |-----------|----------------------------------------------------------------------| | `$0` | 当前行的内容 | | `$1`, `$2`| 表示当前行的第一个字段、第二个字段 | | `NF` | 当前记录中的字段总数 | | `NR` | 已经读取的记录号(全局计数器),适用于所有文件 | | `FNR` | 当前文件已经读取的记录号 | 示例代码展示如何使用这些参数: ```bash echo "John Doe 30" | awk '{print $1, $2, NF}' ``` 假设输入为 `"John Doe 30"`,则输出将是 `John Doe 3`,表明有三个字段[^2]。 --- ##### (2)自定义参数 (`-v`) 可以在运行时传递外部变量至 `awk` 脚本中。例如: ```bash awk -v var=100 'BEGIN{print var*var}' ``` 这条命令会在脚本执行之前设置变量 `var` 的初始值为 `100`,并计算平方值[^2]。 --- #### 其他常见函数分类 ##### (1)字符串函数 除了前面提到的 `length` `split` 外,还有许多其他的字符串操作函数,比如: - `substr(s, m, n)`:获取字符串 `s` 从第 `m` 位开始的连续 `n` 个字符; - `index(s, t)`:找到子串 `t` 在字符串 `s` 中首次出现的位置; - `match(s, r)`:测试正则表达式 `r` 是否能匹配字符串 `s` 并返回起始位置。 ##### (2)算术函数 支持基本数学运算以及更复杂的数值处理,如: - `sqrt(x)`:求平方根; - `sin(x), cos(x)`:三角函数; - `rand(), srand()`:随机数生成及相关初始化。 ##### (3)时间日期相关函数 可用于格式化时间日期显示或解析: - `mktime(datestr)`:将日期字符串转为 Unix 时间戳; - `strftime(format [, timestamp])`:基于模板格式化时间戳; - `systime()`:返回当前系统的 Unix 时间戳。 --- #### 综合实例 下面给出一个综合运用多种功能的例子——统计日志文件中 HTTP 状态码为 `404` 的次数: ```bash awk '$9 ~ /404/ {count++} END {print count}' access.log ``` 在此场景下,我们假定第九列代表响应状态码,当检测到某行为 `404` 错误时增加计数器,在最后阶段报告总计数结果[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值