Shell之awk

一、awk概述

1. awk的工作原理

逐行读取文本,默认以空格或tab键为分隔符进行分割,将分割所得的各个字段保存到内建变量中,并按模式或者条件执行编辑命令。

sed命令常用语一整行的处理,而awk比较倾向于将一行分成多个“字段”然后再进行处理。awk信息的读入也是逐行读取的,执行结果可以通过print的功能将字段数据打印显示。在使用awk命令的过程中,可以使用逻辑操作符“&&”表示“与”、“||”表示“或”、“!”表示“非”;还可以进行简单的数学运算,如+、-、*、/、%、^分别表示加、减、乘、除、取余和乘方。

2. 命令格式

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

awk -f 脚本文件 文件1 文件2 ……

3. awk常见的内建变量(可直接用)

内建变量 说明
FS 列分隔符。指定每行文本的字段分隔符,默认为空格或制表位。与“-F”作用相同
NF 当前处理的行的字段个数
NR 当前处理的行的行号(序数)
$0 当前处理的行的整行内容
$n 当前处理行的第n个字段(第n列)
FILENAME 被处理的文件名
RS 行分隔符。awk从文件上读取资料时,将根据RS的定义把资料切割成许多条记录,而awk一次仅读入一条记录,以进行处理。预设值是“\n”

二、操作实例

1. 按行输出文本

awk '{print}' 文件名

输出所有内容

[root@localhost ~]# cat test.txt
11
22
33
44
[root@localhost ~]# awk '{print}' test.txt
11
22
33
44

awk '{print $0}' 文件名

输出所有内容

[root@localhost ~]# awk '{print $0}' test.txt
11
22
33
44

awk 'NR==n,NR==m {print}' 文件名

输出第n行至第m行的内容

[root@localhost ~]# awk 'NR==1,NR==3 {print $0}' test.txt
11
22
33

awk '(NR>=n) && (NR<=m) {print}' 文件名

输出第n行至第m行的内容

[root@localhost ~]# awk '(NR>=1) && (NR<=3) {print}' test.txt
11
22
33

awk 'NR==n || NR==m {print}' 文件名

输出第n行和第m行的内容

[root@localhost ~]# awk 'NR==1 || NR==3 {print}' test.txt
11
33

awk '(NR%2)==1 {print}' 文件名

输出所有奇数行的内容

[root@localhost ~]# awk '(NR%2)==1 {print}' test.txt
11
33

awk '(NR%2)==0 {print}' 文件名

输出所有偶数行的内容

[root@localhost ~]# awk '(NR%2)==1 {print}' test.txt
22
44

awk '/^a/ {print}' 文件名

输出以字符串a开头的行

[root@localhost ~]# awk '/^3/ {print}' test.txt
33

awk '/a$/ {print}' 文件名

输出以字符串a结尾的行

[root@localhost ~]# awk '/4$/ {print}' test.txt
44

awk 'BEGIN {x=0}; /^a/ {x++}; END {print x}' 文件名

输出文件中以字符串a开头行的数量

BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作;awk再处理指定的文本,之后再执行END模式中指定的动作,END{}语句块中,往往会放入打印结果等语句。

[root@localhost ~]# awk 'BEGIN{X=0}; /^root/ {x++}; END{print x}' /etc/passwd
1
[root@localhost ~]# awk 'BEGIN{X=0}; /nologin$/ {x++}; END{print x}' /etc/passwd
39

2. 按字段输出文本

awk -F ":" '{print $n}' 文件名

以:号为分隔符,输出每行的第n个字段

[root@localhost ~]# awk -F ":" '{print $1}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
operator
games
ftp
nobody
systemd-network
dbus
polkitd
abrt
libstoragemgmt
rpc
colord
saslauth
setroubleshoot
rtkit
pulse
qemu
ntp
radvd
chrony
tss
usbmuxd
geoclue
sssd
gdm
rpcuser
nfsnobody
gnome-initial-setup
avahi
postfix
sshd
tcpdump
123456
named
dhcpd
apache

awk -F ":" '{print $n,$m}' 文件名

以:号为分隔符,输出每行的第n个和第m个字段

[root@localhost ~]# awk -F ":" '{print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4
sync 5
shutdown 6
halt 7
mail 8
operator 11
games 12
ftp 14
nobody 99
systemd-network 192
dbus 81
polkitd 999
abrt 173
libstoragemgmt 998
rpc 32
colord 997
saslauth 996
setroubleshoot 995
rtkit 172
pulse 171
qemu 107
ntp 38
radvd 75
chrony 994
tss 59
usbmuxd 113
geoclue 993
sssd 992
gdm 42
rpcuser 29
nfsnobody 65534
gnome-initial-setup 991
avahi 70
postfix 89
sshd 74
tcpdump 72
123456 1000
named 25
dhcpd 177
apache 48

awk -F ":" '$n<m {print $n}' 文件名

以:号为分隔符,当第n个字段小于m时,输出第n个字段

[root@localhost ~]# awk -F ":" '$3<5 {print $1,$3}' /etc/passwd
root 0
bin 1
daemon 2
adm 3
lp 4

awk -F ":" '!($n<m) {print}' 文件名

以:号为分隔符,当第n个字段不小于m时,输出整行内容

[root@localhost ~]# awk -F ":" '!($3<200) {print}' /etc/passwd
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin
setroubleshoot:x:995:993::/var/lib/setroubleshoot:/sbin/nologin
chrony:x:994:990::/var/lib/chrony:/sbin/nologin
geoclue:x:993:988:User for geoclue:/var/lib/geoclue:/sbin/nologin
sssd:x:992:987:User for sssd:/:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
gnome-initial-setup:x:991:986::/run/gnome-initial-setup/:/sbin/nologin
123456:x:1000:1000:123456:/home/123456:/bin/bash

awk 'BEGIN {FS=":"}; {if ($n>=m) {print}}' 文件名

以:号为分隔符,当第n列大于等于m时,输出整行内容

[root@localhost ~]# awk 'BEGIN {FS=":"}; {if ($3>=1000) {print}}' /etc/passwd
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
123456:x:1000:1000:123456:/home/123456:/bin/bash

awk -F ":" '{max=($n>=$m) ? $n : $m; {print max}}' 文件名

三元运算符。以:号为分隔符,如果第n个字段的值大于等于第m个字段的值,则把第n个字段的值赋给max,否则把第m个字段的值赋给max

[root@localhost ~]# awk -F ":" '{max=($3>=$4) ? $3 : $4; {print max}}' /etc/passwd
0
1
2
4
7
5
6
7
12
11
100
50
99
192
81
999
173
998
32
997
996
995
172
171
107
38
75
994
59
113
993
992
42
29
65534
991
70
89
74
72
1000
25
177
48

awk -F ":" '{print NR,$0}' 文件名

以:号为分隔符,处理每行内容和行号,没处理完一条记录,NR值加1

[root@localhost ~]# awk -F ":" '{print NR,$0}' /etc/passwd
1 root:x:0:0:root:/root:/bin/bash
2 bin:x:1:1:bin:/bin:/sbin/nologin
3 daemon:x:2:2:daemon:/sbin:/sbin/nologin
4 adm:x:3:4:adm:/var/adm:/sbin/nologin
5 lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
6 sync:x:5:0:sync:/sbin:/bin/sync
7 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
8 halt:x:7:0:halt:/sbin:/sbin/halt
9 mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
10 operator:x:11:0:operator:/root:/sbin/nologin
11 games:x:12:100:games:/usr/games:/sbin/nologin
12 ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
13 nobody:x:99:99:Nobody:/:/sbin/nologin
14 systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
15 dbus:x:81:81:System message bus:/:/sbin/nologin
16 polkitd:x:999:997:User for polkitd:/:/sbin/nologin
17 abrt:x:173:173::/etc/abrt:/sbin/nologin
18 libstoragemgmt:x:998:995:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
19 rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
20 colord:x:997:994:User for colord:/var/lib/colord:/sbin/nologin
21 saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin
22 setroubleshoot:x:995:993::/var/lib/setroubleshoot:/sbin/nologin
23 rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
24 pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
25 qemu:x:107:107:qemu user:/:/sbin/nologin
26 ntp:x:38:38::/etc/ntp:/sbin/nologin
27 radvd:x:75:75:radvd user:/:/sbin/nologin
28 chrony:x:994:990::/var/lib/chrony:/sbin/nologin
29 tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
30 usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
31 geoclue:x:993:988:User for geoclue:/var/lib/geoclue:/sbin/nologin
32 sssd:x:992:987:User for sssd:/:/sbin/nologin
33 gdm:x:42:42::/var/lib/gdm:/sbin/nologin
34 rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
35 nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
36 gnome-initial-setup:x:991:986::/run/gnome-initial-setup/:/sbin/nologin
37 avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
38 postfix:x:89:89::/var/spool/postfix:/sbin/nologin
39 sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
40 tcpdump:x:72:72::/:/sbin/nologin
41 123456:x:1000:1000:123456:/home/123456:/bin/bash
42 named:x:25:25:Named:/var/named:/sbin/nologin
43 dhcpd:x:177:177:DHCP server:/:/sbin/nologin
44 apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin

awk -F ":" '$n~ "a" {print $m}' 文件名

以:号为分隔符,输出第n个字段中含有字符串a的行的第m个字段

[root@localhost ~]# awk -F ":" '$7~ "/bash" {print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
123456:x:1000:1000:123456:/home/123456:/bin/bash

awk -F ":" '($n~ "a") && (NF==m) {print}' 文件名

以:号为分隔符,输出第n个字段中含有字符串a且有m个字段的行

[root@localhost ~]# awk -F ":" '($1~ "root") && (NF==7) {print $1,$2}' /etc/passwd
root x

awk -F “:” '($n != "a") && ($m != "b") {print}' 文件名

以:号为分隔符,输出第n个字段既不是字符串a也不是字符串b的行

[root@localhost ~]# awk -F ":" '($7!="/bin/bash")&&($7!="/sbin/nologin") {print}' /etc/passwd
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt

通过管道、双引号调用Shell命令

echo $PATH | awk 'BEGIN{RS=":"}; END{print NR}'

以:号为分隔符,输出总字段数

[root@localhost ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]# echo $PATH | awk 'BEGIN{RS=":"}; END{print NR}'
5

awk -F: '/a$/ {print | "wc -l"}' 文件名

以:号为分隔符,统计以字符串a为结尾的行的行数,同等于“grep -c”命令

[root@localhost ~]# awk -F: '/bash$/ {print | "wc -l"}' /etc/passwd
2
[root@localhost ~]# grep -c "/bash"$ /etc/passwd
2

free -m | awk '/Mem:/ {print int($3/($3+$4)*100)"%"}'

查看当前内存使用百分比

[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 1984 326 1257 9 400 1439
Swap: 4095 0 4095
[root@localhost ~]# free -m | awk '/Mem:/ {print int($3/($3+$4)*100)"%"}'
20%

top -b -n 1 | grep Cpu | awk -F "," '{print $4}' | awk '{print $1}'

查看当前CPU空闲率,"-b -n 1"表示只需要1次的输出结果

[root@localhost ~]# top -b -n 1 | grep Cpu | awk -F "," '{print $4}' | awk '{print $1}'
97.0

date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H:%M:%S"

显示上次系统重启时间,等同于uptime;“second ago”为显示多少秒前的时间,+"%F %H:%M:%S"为时间格式,%F等同于%Y-%m-%d。

[root@localhost ~]# date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H:%M:%S"
2021-07-29 11:07:15

awk 'BEGIN {N=0; while ("w" | getline) n++; {print n=2}}'

调用w命令,并用来统计在线用户数

[root@localhost ~]# awk 'BEGIN {N=0; while ("w" | getline) n++; {print n=2}}'
2

awk 'BEGIN {"hostname" | getline; {print}}'

调用hostname,并输出当前的主机名

[root@localhost ~]# awk 'BEGIN {"hostname" | getline; {print}}'
localhost.localdomain

注:当getline左右无重定向符“<”或“|”时,awk首先读取到了第一行,就是1,然后getline,就得到了1下面的第二行,就是2,因为getline之后,awk会改变对应的NF,FNR和$0等内部变量,所以此时的$0的值就不再是1,而是2了,然后将它打印出来。

当getline左右有重定向符“<”或“|”时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。

FNR:awk当前读取的记录数,其变量值小于等于NR(比如当读取第二个文件时,FNR是从0开始重新计数,而NR不会),因此可使用“NR==FNR”来判断是否在读取第一个文件。

[root@localhost ~]# seq 10 | awk '{getline; print}'
2
4
6
8
10
[root@localhost ~]# seq 10 | awk '{print; getline}'
1
3
5
7
9

CPU使用率

[root@localhost ~]# cat cpu.sh
#!/bin/bash cpu_us=`top -b -n 1 | grep Cpu | awk '{print $2}'`
echo $cpu_us
cpu_sy=`top -b -n 1 | grep Cpu | awk -F ',' '{print $2}' | awk '{print $1}'`
echo $cpu_sy
echo "$cpu_us+$cpu_sy" | bc
[root@localhost ~]# ./cpu.sh
0.0
3.1
3.1

echo "A B C D" | awk '{OFS="|"; print $0 ;$1=$1; print $0}'

$1=$1是用来重新激活$0的重新赋值,也就是说每一个字段和字段数NF的改变会促使awk重新计算$0的值,通常是在改变OFS后面需要输出$0时这样做。

[root@localhost ~]# echo "A B C D" | awk '{OFS="|"; print $0 ;$1=$1; print $0}'
A B C D
A|B|C|D

3. awk数组循环

  1. 使用awk建立数组

    awk 'BEGIN {a[0]=10; a[1]=20; print a[0]}'

    awk 'BEGIN {a[0]=10; a[1]=20; print a[1]}'
[root@localhost ~]# awk 'BEGIN {a[0]=10; a[1]=20; print a[0]}'
10
[root@localhost ~]# awk 'BEGIN {a[0]=10; a[1]=20; print a[1]}'
20

awk 'BEGIN {a["abc"]=10; a["xyz"]=20; print a["abc"]}'

awk 'BEGIN {a["abc"]=10; a["xyz"]=20; print a["xyz"]}'

[root@localhost ~]# awk 'BEGIN {a["abc"]=10; a["xyz"]=20; print a["abc"]}'
10
[root@localhost ~]# awk 'BEGIN {a["abc"]=10; a["xyz"]=20; print a["xyz"]}'
20

awk 'BEGIN {a["abc"]="aabbcc"; a["xyz"]="xxyyzz"; print a["abc"]}'

awk 'BEGIN {a["abc"]="aabbcc"; a["xyz"]="xxyyzz"; print a["xyz"]}'

[root@localhost ~]# awk 'BEGIN {a["abc"]="aabbcc"; a["xyz"]="xxyyzz"; print a["abc"]}'
aabbcc
[root@localhost ~]# awk 'BEGIN {a["abc"]="aabbcc"; a["xyz"]="xxyyzz"; print a["xyz"]}'
xxyyzz

awk 'BEGIN {a[0]=10; a[1]=20; a[2]=30; for (i in a) {print i,a[i]}}'

[root@localhost html]# awk 'BEGIN {a[0]=10; a[1]=20; a[2]=30; for (i in a) {print i,a[i]}}'
0 10
1 20
2 30

注1:BEGIN中的命令只执行一次

注2:awk数组的下标除了可以使用数字,也可以使用字符串,字符串需要使用双引号

  1. awk循环遍历
[root@localhost ~]# cat test1.txt
aaa
aaa
bbb
ccc
aaa
bbb
aaa
[root@localhost ~]# awk '{a[1]++} END{for(i in a) {print a[i]}}' test1.txt
7

注:a[1]初始为0,a[1]++后即为1,而这里awk中的a[1]++最终的值是由test1.txt文本内容有多少行决定的,文本逐行读取完毕后再执行END中的命令。

使用awk获取文件test1.txt中的重复行及次数

[root@localhost ~]# awk '{a[$1]++} END{for(i in a) {print a[i],i}}' test1.txt
4 aaa
1 ccc
2 bbb
[root@localhost ~]# awk '{a[$1]++} END{for(i in a) {print a[i],i}}' test1.txt | sort -r
4 aaa
2 bbb
1 ccc

注:也可使用sort排序后通过“uniq -c”获取重复行次次数。以上操作是我们在日常工作中常用的运维手段,crontab日常监控以及排障时经常用得到。

扩展--运维工作常用的查看命令或文件

监控项目 监控命令或文件
cpu负载 uptime
内存容量 free -m
硬盘空间 df -h
网卡流量 ifconfig 网卡名称(如ens33)
安装的软件包数量 rpm -qa | wc -l
账户数量 /etc/passwd
当前登录的账户数量 who
进程数量 ps aux
异常登录信息 /var/log/secure

例如:

使用awk统计httpd访问日志中每个客户端IP的出现次数

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

[root@localhost ~]# awk '{ip[$1]++} END{for (i in ip) {print ip[i],i}}' /var/log/httpd/access_log | sort -r
82 192.168.122.88

注:定义数组,数组名称为ip,数字的下标为日志文件的第1列(也就是客户端的IP地址),++的目的在于对客户端进行统计技术,客户端IP出现一次计数器就加1.END中的指令在读取完文件后执行,通过循环将所有统计信息输出,for循环遍历的是数组名ip的下标。

Shell之awk的更多相关文章

  1. AWK增强的文本处理shell特征--AWK完全手册

    AWK这是一个很好的文字处理工具. 它不仅 Linux 中也是不论什么环境中现有的功能最强大的数据处理引擎之中的一个. 本文主要摘录池中龙写的Unixawk使用手冊(第二版),对当中内容略微修改.感谢 ...

  2. CU社区shell板块awk十三问整理

    CU社区shell板块awk十三问整理 一.RS="" 当 RS="" 时,会将\n强制加入到FS变量中,因为RS为空时,是将连续多空行作为分隔符,近似于\n\ ...

  3. Shell 学习—AWK介绍

    Shell 学习—AWK = = = 安装awk root@kiki-desktop:~/shell# apt-get install gawk gawk-doc = = = awk 是一种程序语言. ...

  4. shell中awk用法

    简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再 ...

  5. shell 统计 awk

    time awk '{a[$1]++}END{for(i in a){printf("%d\t%s\n",a[i],i)}}' access.log | sort -nr | he ...

  6. shell 之awk 关联数组高级应用

    最近由于数据迁移过,有些用户信息需要再次确认下,也许数据量比较大,但是需要最终确认的比如说是用户ID和其对应的用户积分数,这样就会导致出现文本a(老的数据),文本b(新的数据).比如 这是文本a.tx ...

  7. shell脚本 awk工具

    awk工具概述awk编程语言/数据处理引擎基于模式匹配检查输入文本,逐行处理并输出通常在shell脚本中,或取指定的数据单独用时,可对文本数据做统计 命令格式格式一:awk [选项] '[条件]{编辑 ...

  8. 【shell】awk按域去除重复行

    首先解释一下什么叫“按域去除重复行”: 有的时候我们需要去除的重复行并不是整行都重复,两行的其中一列的元素相同我们有的时候就需要认定这两行重复,因此有了今天的内容. 去除重复行shell有一个原生命令 ...

  9. shell编程awk进阶

    awk操作符 算术操作符:  x+y, x-y, x*y, x/y, x^y, x%y      -x: 转换为负数      +x: 转换为数值 字符串操作符:没有符号的操作符,字符串连接 赋值操作 ...

随机推荐

  1. Jsonschema2pojo从JSON生成Java类(命令行)

    1.说明 jsonschema2pojo工具可以从JSON Schema(或示例JSON文件)生成Java类型, 在文章Jsonschema2pojo从JSON生成Java类(Maven) 已经介绍过 ...

  2. frontend-maven-plugin插件问题解决

    1.插件介绍 frontend-maven-plugin为项目本地下载/安装Node和NPM,运行npm install命令 . 它适用于Windows,OS X和Linux. 这个插件也可以下载No ...

  3. Kylin启动步骤

    Kylin本身的启动命令比较简单, 但是由于Kylin依赖的其他组件比较多, 所以把完整的启动步骤整理一下. 1.确保集群时间同步 首先查看集群中的时间是否同步 date 如果时间不一致,需要使用如下 ...

  4. mt19937

    额,这个是一个小记.没什么,就是记给自己看的,你可以走了. mt19937 需要 C++11.生成高质量随机数. mt19937 rnd(chrono::system_clock::now().tim ...

  5. JDK线程池异常处理方式

    1. 抛出异常 execute() java.util.concurrent.ThreadPoolExecutor#runWorker 中抛出,抛出之后经过以下两个步骤: catch块捕获,捕获之后再 ...

  6. react中create-react-app详情配置文档

    https://facebook.github.io/create-react-app/docs/documentation-intro

  7. Itellij Idea使用

    图片如果损坏,点击链接查看 https://www.toutiao.com/i6491635946176381454/ 创建Maven项目 JDK环境 目前大多数IDE都没有集成JDK环境,IDEA也 ...

  8. 微信小程序封装mixins方法

    在app.js中这样引入 import '@src/utils/mixins' mixins函数如下 /** * 封装类似vue的混入功能 */ let native = Page Page = (o ...

  9. 在Rainbond上使用Locust进行压力测试

    Locust简介 Locust 是一种易于使用.可编写脚本且可扩展的性能测试工具.并且有一个用户友好的 Web 界面,可以实时显示测试进度.甚至可以在测试运行时更改负载.它也可以在没有 UI 的情况下 ...

  10. csapp lab2 拆炸弹

    1. 实验内容 包含一个二进制应用bomb,需要根据该应用猜测程序的运行过程.程序主体包含了六个函数phase_1到phase_6,每个函数会根据用户的输入做出反应,当输入符合要求时,会炸弹拆解成功, ...