确定需求、编写demo
这是一个很有意思的事情,今天下午,有人找到运维小弟我,帮忙分析脚本报错: 分析下来后,发现核心需求点是:定义一个数组,然后获取一个字符串,判断该字符串是否出现在数组中。
其大概可以图示为如下:
作为运维的我,心想,这多简单啊,撸起袖子就写了起来,不一会,该demo
已经写出来了,如下:
#!/bin/bash # pdudo # 2023年3月30日 # 定义数组 array array=(pdudo1 pdudo2 pdudo4 pdudo5) # 定义字符串 searchString="pdudo1" # 定义循环 遍历数组 和 字符串相匹配 for value in ${array[@]}; do # 判断是否相等 if [ $value = $searchString ];then # 输出相等信息 echo "$searchString 出现在数组中" fi done
上述代码,先定义了数组array,其值为 pdudo1 pdudo2 pdudo4 pdudo5
, 而后定义了 字符串值为 pdudo1
, 判断是否出现在数组中的语法,则是 循环获取 数组的值,和 字符串进行匹配,若匹配成功,则输出信息。
代码截图:
执行后,发现正如我们期待所言。
于是乎,就将该代码,整合进项目,给开发发过去了,当然作为老手而言,整个过程不超过15分钟,肯定获得了掌声和欢呼声。
完事之后,想着chatgpt
会如何去编写该需求呢,于是抱着好奇心,上去问了一下。
使用chatgpt帮我们写代码
使用bash内置方法=~
要询问chatgpt
,我们需要先明确需求,例如,我将上述需求给整理了一下,定义如下:
用bash脚本定义一个数组,其值为 append append2 append3 , 写一个程序,接收一个值,用以判断是否在数组中。
很快,chatgpt
就回复我们了,其信息如下:
嘿,定睛一看,和我上述写的demo
是一样的,不由得,我飘了。
于是再度发问,是否还有更加简单的方法呢?
额,这就有点尴尬了,原来bash
有这个方法(=~
)来判断字符串是否出现在数组中,自己还苦哈哈的写循环的方法,于是乎,修改了一下,用于验证是否准确,其脚本如下:
#!/bin/bash # pdudo # 2023年3月30日 # 定义数组 array array=(pdudo1 pdudo2 pdudo4 pdudo5) # 定义字符串 searchString="pdudo1" # 判断是否相等 if [[ ${array[@]} =~ $searchString ]];then # 输出相等信息 echo "$searchString 出现在数组中" fi
执行后,发现确实能够达成需求。
代码截图
运行效果
于是乎,去查询了一下该方法,终于搞清楚了这个东东,=~
是bash
的特性,必须双引号[[ ]]
括起来,语法结构为 数组值 =~ 匹配字符串
,返回值为0
则是匹配成功,返回值为1
则是匹配失败。
我们可以编写脚本测试一下:
上述代码中的$?
表示上一个命令的返回值,即命令: [[ ${array[@]} =~ $searchString ]]
执行后效果如下
可见分析的没问题,又学到了,赞赞赞。
使用关联数组
学习完上诉使用bash
内置方法=~
后,接着,问下是否还有其他方法可以解决该问题。
这个就很熟悉了,所谓的关联数组,大可将其理解为 hash
字典 即可,而代码中的declare
是在定义属性,对,没看错哦,bash
也是可以定义属性的,比如变量只读,定义为函数 ,定义为 拥有下标的数组 , 定义为 关联数组 等等,可以通过man bash
获取更多的信息。
这里就不再阐述了,根据chatgpt
提供的案例,我们修改一下脚本,可以将其更改为:
#!/bin/bash # pdudo # 2023年3月30日 # 定义数组 array array=(pdudo1 pdudo2 pdudo4 pdudo5) # 定义关联数组 declare -A dictArray for v in ${array[@]} do dictArray[$v]=1 done # 定义字符串 searchString="pdudo1" # 判断是否出现在数组中 if [ ${dictArray[$searchString]} ];then echo "$searchString 出现在数组中" else echo "$searchString 不出现在数组中" fi
由于我们定义的是下标形的数组,所以需要先将其转换为关联数组,而后直接判断该关联数组,即可判断是否出现在数组中了,这个就不掩饰了。
自定义数组
再得到2种方法之后,在此询问,是否还有其他方法,当然chatgpt
果然没让我失望,返回了这样的结果:
chatgpt
上面提供的代码,其实在机器上不能运行,需要将其函数定义调整到调用之前才行。
初看,细看,再仔细看,这。。。。tm是什么代码,直接给我干破防了。
我们来分析下,这函数定义的到底是个啥,我们拷贝函数出来:
# 定义in_array函数 function in_array() { local e match="$1" shift for e; do [[ "$e" == "$match" ]] && return 0; done return 1 }
其中,local
是定义局部变量,若不指定,则定义的是全局变量,而sfift
则是将参数列表向左移动一个位置,额。。。e是啥意思? 先不急,我们可以改改脚本,修改如下:
# 定义数组 in_array function in_array() { # 获取传入的第一个参数 local key=$1 # 参数向左偏移一位 shift # 获取所有参数 local array=$* # 循环数组 for v in $array do # 判断是否相等 if [ $v = $key ];then return 0 fi done return 1 }
结合上面的讲解,这样是否看起来,是否很熟悉了呢?
我们验证下代码是否可行,代码如下:
执行后,结果如下:
再反过头来看这个函数:
# 定义in_array函数 function in_array() { local e }
在bash
中,此时e
已经获取到了全部的参数,当然不能通过echo
来输出变量e
的值,需要借助for
循环,我们可以看这个例子:
#!/bin/bash # pdudo # 2023年3月30日 # 定义函数 function in_array() { local a for a do echo $a done } # 执行函数 in_array 1 2 3 5 6
运行一下,直接结果为:
运行结果符合我们预期
总结
很久没写文章了,也不给自己找借口,就是因为懒,今天这篇文章是有感而发,chatgpt
真的非常强大了,要好好的利用起来才行,暴力破解不是唯一的解法,再简单的需求,也许也会有更的优解法,想让代码变得更骚么? 借助chatgpt
让你更上一层楼吧。
也许有一天,干掉我们的不是chatgpt
,而是更善用chatgpt
的人,就这样吧。