Bash基础 - Awk 和 Sed
同学做入职在线测试,遇到一道Bash程序题,不太会做所以来问我。我之前对Bash也是一知半解,一边查资料一边摸索给做出来了,中间遇到很多难点,于是想借此机会深入学习Bash的知识,并记录下来,加深记忆。本篇记录一下Awk和Sed相关知识。真题在最后。
Awk
输入
默认输入方式为:
ask SCRIPT INPUT.FILE
但更常用的是使用管道:
echo FILE.or.VARIABLE | awk SCRIPT
分隔符
Awk默认使用空格分隔。因此一个常见的Awk参数是 -F
指定分隔符,比如指定,
为分隔符:
echo ${demo} | awk -F ',' '{print NF}'
-F
参数也支持正则表达式,比如指定,
或:
为分隔符:
echo ${demo} | awk -F '[,:]' '{print NF}'
参数脚本
处理简单任务时,一般使用参数脚本,也就是直接在参数中写处理逻辑,以上例子均为参数脚本
比如在测试中的获取JSON对象中的email值:
email=$(echo "${json}" | awk -F '[,:}]' '{for(i=1;i<=NF;i++){if($i~/email/){print $(i+1)}}}')
其中 if
条件内为正则表达式
~
表示匹配!~
表示不匹配
需要注意的一点是,一般使用单引号'
包裹Awk的参数,避免被Bash先行释义,必要时可以通过拼接字符串来实现比较复杂的逻辑。
文件脚本
1 | #!/bin/awk -f |
Sed
输入
与Awk一致:
sed PATTERN INPUT.FILE
或者
echo FILE.or.VARIABLE | sed PATTERN
正则模式
's/reg/res/g'
- s表示替换
- g表示替换全部,可选
- reg为模式,与正则基本规则一致
- res为替换的内容
一些例子:
3s/reg/res/g
,替换第三行3,6s/reg/res/g
,替换第三至六行3s/reg/res/1
,替换第三行第一个3s/reg/res/3g
,替换第三行第三个以及之后的
其他
()
- 用法一
- 在子
bash
中运行命令,比如(cd ~; touch aa.bb)
- 在子
- 用法二
- 生成数组,
a=(1 3 5)
或者a=($(echo $demo | awk '{for(i=1;i<=NF;i++){print $i}}'))
- 生成数组,
尽量${a}
代替$a
- 边界容易区分,如
$ab
- 有更多功能,
${a/reg_old/reg_new}
可以正则替换,${a//reg_old/reg_new}
可以正则替换全部,
$(cmd)
执行cmd命令的结果,或赋值,等价于``
,但后者容易看错
(())与$(())
计算表达式,比如((a++))
[] 与 [[]]
[[]]
是[]
加强版,等价于test
,做条件判真用,比如 if [[ $a == 0 ]]; then echo 'a==0'; fi
真题
You have the following API endpoint:
https://reqres.in/api/users (Description can be found here: https://reqres.in)
Create a Bash script that calls the API. From the result, extract the user object of George Edwards (yes, the user exists). In the user object, change the mail (locally, no need to call any API from here) to edwards.george@reqres.in and store the object to a file.
Do not use temporary files, all needs to happen in memory. You can assume that you can use the typically installed Linux command line tools in your bash script (including sed, jq, tee, grep).
Please provide your Bash-only script.
Bonus task: store all the users within this API including the particular change as mentioned above in a file.
我的代码
1 |
|