shell/awk/awk-数组与函数.md
2025-03-30 13:46:10 +08:00

226 lines
5.2 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<h2><center>awk 数组与函数</center></h2>
------
## 一:数组
`awk`可以使用关联数组这种数据结构,索引可以是数字或字符串。
`awk`关联数 组也不需要提前声明其大小,因为它在运行时可以自动的增大或减小。
### 1. 语法格式
```shell
array_name[index]=value
```
- array_name数组的名称
- index数组索引
- value数组中元素所赋予的值
### 2. 创建数组
定义了一个站点(sites)数组,该数组的索引为网站英文简称,值为网站访问地址。
```bash
[root@wxin ~]# awk 'BEGIN {
sites["qfedu"]="www.qfedu.com";
sites["google"]="www.google.com"
print sites["qfedu"] "\n" sites["google"]
}'
www.qfedu.com
www.google.com
```
### 3. 访问数组
访问数组元素语法格式
```shell
array_name[index]
```
访问数组元素
```bash
[root@wxin ~]# awk -F: '{username[++i]=$1} END{print username[1]}' /etc/passwd
root
[root@wxin ~]# awk -F: '{username[i++]=$1} END{print username[1]}' /etc/passwd
bin
[root@wxin ~]# awk -F: '{username[i++]=$1} END{print username[0]}' /etc/passwd
root
```
按元数个数遍历
```bash
[root@wxin ~]# awk -F: '{username[x++]=$1} END{for(i=0;i<x;i++) print i,username[i]}' /etc/passwd
0 root
1 bin
2 daemon
3 adm
4 lp
5 sync
6 shutdown
7 halt
[root@wxin ~]# awk -F: '{username[++x]=$1} END{for(i=1;i<=x;i++) print i,username[i]}' /etc/passwd
1 root
2 bin
3 daemon
4 adm
5 lp
6 sync
7 shutdown
8 halt
9 mail
10 operator
```
按索引遍历
```bash
[root@wxin ~]# awk -F: '{username[x++]=$1} END{for(i in username) {print i,username[i]} }' /etc/passwd
17 sshd
4 lp
18 postfix
5 sync
19 mysql
6 shutdown
7 halt
8 mail
9 operator
10 games
20 nginx
[root@wxin ~]# awk -F: '{username[++x]=$1} END{for(i in username) {print i,username[i]} }' /etc/passwd
17 tss
4 adm
18 sshd
5 lp
19 postfix
6 sync
7 shutdown
8 halt
9 mail
10 operator
20 mysql
11 games
# 注变量i是索引
```
### 4. 删除元素
删除数组元素语法格式
```shell
delete array_name[index]
```
**删除数组元素**
删除数组中的 google 元素(删除命令没有输出):
```bash
[root@wxin ~]# awk 'BEGIN {
sites["qfedu"]="www.qfedu.com";
sites["google"]="www.google.com"
delete sites["google"];
print fruits["google"]
}'
```
### 5. 多维数组
AWK 本身不支持多维数组,不过我们可以很容易地使用一维数组模拟实现多维数组。
如下示例为一个 3x3 的三维数组:
```shell
100 200 300
400 500 600
700 800 900
```
实例中array0 存储 100array0 存储 200 ,依次类推。
要在 array0 处存储 100, 使用: array["0,0"] = 100。
使用 0,0 作为索引,这并不是两个索引值,而是一个字符串索引 0,0。
**模拟二维数组**
```bash
[root@wxin ~]# awk 'BEGIN {
array["0,0"] = 100;
array["0,1"] = 200;
array["0,2"] = 300;
array["1,0"] = 400;
array["1,1"] = 500;
array["1,2"] = 600;
# 输出数组元素
print "array[0,0] = " array["0,0"];
print "array[0,1] = " array["0,1"];
print "array[0,2] = " array["0,2"];
print "array[1,0] = " array["1,0"];
print "array[1,1] = " array["1,1"];
print "array[1,2] = " array["1,2"];
}'
array[0,0] = 100
array[0,1] = 200
array[0,2] = 300
array[1,0] = 400
array[1,1] = 500
array[1,2] = 600
```
在数组上可以执行很多操作,比如,使用 asort 完成数组元素的排序,或者使用 asorti 实现数组索引的排序等等。
## 二:函数
awk的函数有许多除了系统自带的内建函数还有就是用户自定义的函数。
**AWK 常用的函数**
```shell
rand() # 返回0 和1 之间一个随机数
srand() # 生成随机数种子
int() # 取整数
length([s]) # 返回指定字符串的长度
sub(r,s,[t]) # 对t字符串进行搜索r表示的模式匹配的内容并将第一个匹配的内容替换为s
gsub(r,s,[t]) # 对t字符串进行搜索r表示的模式匹配的内容并全部替换为s所表示的内容
split(s,array,[r])# 以r为分隔符切割字符串s并将切割后的结果保存至array 所表示的数组中第一个索引值为1, 第二个索引值为2,…也就是说awk的数组下标是从1开始编的
substr(s,i,[n]) # 从s所表示的字符串中取子串取法从i表示的位置开始取n个字符。
systime() # 取当前系统时间,结果形式为时间戳。
system() # 调用shell中的命令。空格是awk中的字符串连接符如果system中需要使用awk中的变量可以使用空格分隔或者说除了awk的变量外其他一律用""引用起来。
```
**自定义函数示例**
```shell
function fname ( arg1,arg2 , ... ) {
statements
return expr
}
```
- fname为函数名
- arg1...为函数的参数,
- statements是动作语言
- return expr为由 statements 的结果从而决定最终函数所显示的内容。
**自定义函数示例**
```bash
[root@wxin ~]# cat fun.awk
function max(v1,v2) {
v1>v2?var=v1:var=v2
return var
}
BEGIN{a=3;b=2;print max(a,b)}
awk f fun.awk
```