shell/awk/awk-流程控制.md
2025-03-30 13:46:10 +08:00

440 lines
7.5 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>
------
## 一:流程控制
### 1. 条件
#### 1. if 语句
**`if`条件语句语法格式**
```shell
if (condition)
action
```
**使用花括号语法格式**
```shell
if (condition)
{
action1;
action2;
...
}
{if(表达式)语句1;语句2;...}
```
**示例:**
判断数字是奇数还是偶数
```bash
[root@wxin ~]# awk 'BEGIN {num = 10; if (num % 2 == 0) printf "%d 是偶数\n", num }'
10 是偶数
```
判断 root 是不是 administrator
```bash
[root@wxin ~]# awk -F: '{if($3==0) {print $1 " is administrator."}}' /etc/passwd
root is administrator.
```
统计系统用户数
```bash
[root@wxin ~]# awk -F: '{if($3>0 && $3<1000){count++;}} END{print count}' /etc/passwd  
20
```
#### 2. if - else 语句
**`if - else`条件语句语法格式**
```shell
if (condition)
action1
else
action2
```
**使用花括号语法格式**
```shell
{if (condition)
{
action1;
action2;
...
}
else
{
action1;
action2;
...
}}
{if(表达式)语句1;语句2;...else{语句1;语句2;...}}
```
**示例:**
判断数字是奇数还是偶数
```bash
[root@wxin ~]# awk 'BEGIN {
num = 11;
if (num % 2 == 0) printf "%d 是偶数\n", num;
else printf "%d 是奇数\n", num
}'
11 是奇数
```
判断用户为root就打印用户名否则打印shell类型
```bash
[root@wxin ~]# awk -F: '{if($3==0){print $1} else {print $7}}' /etc/passwd
root
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin
/bin/sync
/sbin/shutdown
```
统计管理员数量和系统用户数量
```bash
[root@wxin ~]# awk -F: '{if($3==0){count++} else{i++}} END{print "管理员个数: "count ; print "系统用户数: "i}' /etc/passwd
管理员个数: 1
系统用户数: 20
```
#### 3. if - else - if 语句
**`if - else - if`条件语句语法格式**
```shell
{if (condition1)
{
action1;
action2;
...
}
else if (condition2)
{
action1;
action2;
...
}
else if (condition3)
{
action1;
action2;
...
}
else
{
action1;
action2;
...
}}
{if(表达式1)语句1;语句2...else if(表达式2)语句1;语句2...else if(表达式3)语句1;语句2...else语句1;语句2...}
```
**示例:**
多级判断结果
```bash
[root@wxin ~]# awk 'BEGIN {
a=30;
if (a==10)
print "a = 10";
else if (a == 20)
print "a = 20";
else if (a == 30)
print "a = 30";
}'
a = 30
```
统计管理员,系统,普通用户数量
```bash
[root@wxin ~]# awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print i; print k; print j}' /etc/passwd
1
20
[root@wxin ~]# awk -F: '{if($3==0){i++} else if($3>999){k++} else{j++}} END{print "管理员个数: "i; print "普通用个数: "k; print "系统用户: "j}' /etc/passwd
管理员个数: 1
普通用个数:
系统用户: 20
```
### 2. 循环
#### 1. for 循环
**语法:**
```shell
for(variable addignment; condition; iteration peocess)
{
statement1
statement2
...
}
```
for 语句首先执行初始化动作( initialisation ),然后再检查条件( condition )。如果条件为真,则执行动作( action ),然后执行递增( increment )或者递减( decrement )操作。只要条件为 true 循环就会一直执行。每次循环结束都会进条件检查,若条件为 false 则结束循环。
**示例:**
For 循环输出数字 1 至 5
```bash
[root@wxin ~]# awk 'BEGIN { for (i = 1; i <= 5; ++i) print i }'
1
2
3
4
5
```
For 循环输出数字 1 至 9 的奇数之和
```bash
[root@wxin ~]# echo "hello" | awk '
{
total = 0
for(i=1; i<10; i++)
{
if(i % 2 == 0)
{
continue
}
total = total + i
}
print "total=", total
}'
```
将每行打印10次
```bash
[root@wxin ~]# awk -F: '{ for(i=1;i<=10;i++) {print $0} }' /etc/passwd
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
```
分别打印每行的每列
```bash
[root@wxin ~]# awk -F: '{ for(i=1;i<=NF;i++) {print $i} }' /etc/passwd
root
x
0
0
root
/root
/bin/bash
bin
x
1
1
bin
/bin
/sbin/nologin
```
#### 2. while 循环
**语法:**
```shell
while(condition)
{
statement1
statement2
...
}
```
While 循环首先检查条件 condition 是否为 true ,若条件为 true 则执行动作 action。此过程一直重复直到条件 condition 为 flase 才停止。
**示例:**
While 循环输出数字 1 到 5
```bash
[root@wxin ~]# awk 'BEGIN {i = 1; while (i < 6) { print i; ++i } }'
1
2
3
4
5
[root@wxin ~]# awk 'BEGIN{ i=1; while(i<=5){print i; i++} }'
1
2
3
4
5
```
While 循环输出数字 1 至 9 的奇数之和
```bash
[root@wxin ~]# echo "hello" | awk '
{
total = 0
i = 1
while(i < 10)
{
if(i % 2 == 0)
{
i++
continue
}
total = total + i
i++
}
print "total=", total
}'
```
打印第一行的前七列
```bash
[root@wxin ~]# awk -F: '/^root/{i=1; while(i<=7){print $i; i++}}' /etc/passwd
root
x
0
0
root
/root
/bin/bash
```
分别打印每行的每列
```bash
[root@wxin ~]# awk '{i=1; while(i<=NF){print $i; i++}}' /etc/hosts
127.0.0.1
localhost
localhost.localdomain
localhost4
localhost4.localdomain4
::1
localhost
localhost.localdomain
localhost6
localhost6.localdomain6
```
#### 3. break 结束循环
break[n]当第n次循环到来后结束整个循环n=0就是指本次循环
当计算的和大于 50 的时候使用 break 结束循环:
```bash
[root@wxin ~]# awk 'BEGIN {
sum = 0; for (i = 0; i < 20; ++i) {
sum += i; if (sum > 50) break; else print "Sum =", sum
}
}'
Sum = 0
Sum = 1
Sum = 3
Sum = 6
Sum = 10
Sum = 15
Sum = 21
Sum = 28
Sum = 36
Sum = 45
```
#### 4. continue 跳出本次循环
Continue 语句用于在循环体内部结束本次循环,从而直接进入下一次循环迭代。
Continue[n]满足条件后直接进行第n次循环本次循环不在进行n=0也就是提前结束本次循环而直接进入下一轮
输出 1 到 20 之间的偶数:
```bash
[root@wxin ~]# awk 'BEGIN {for (i = 1; i <= 20; ++i) {if (i % 2 == 0) print i ; else continue} }'
2
4
6
8
10
12
14
16
18
20
```
#### 5. exit 结束脚本程序
Exit 用于结束脚本程序的执行。
该函数接受一个整数作为参数表示 AWK 进程结束状态。 如果没有提供该参数,其默认状态为 0。
当和大于 50 时结束 AWK 程序。
```bash
[root@wxin ~]# awk 'BEGIN {
sum = 0; for (i = 0; i < 20; ++i) {
sum += i; if (sum > 50) exit(10); else print "Sum =", sum
}
}'
Sum = 0
Sum = 1
Sum = 3
Sum = 6
Sum = 10
Sum = 15
Sum = 21
Sum = 28
Sum = 36
Sum = 45
```
检查脚本执行后的返回状态
```bash
[root@wxin ~]# echo $?
10
```
#### 6. next 停止处理
next提前结束对本行的处理动作而直接进入下一行处理
```bash
[root@wxin ~]# awk -F: '{if($3%2!=0) next; print $1,$3}' /etc/passwd
```