大家好呀,今天是周三,早点下班给大家肝文章的awk 下期,顺便给大家做个预告,后面会开新的一个专题,讲一下Rust 这个编程语言的知识和入门(咱也蹭蹭热度),我用Rust 也有两年多的时间了,虽然没有用c++ 那么六六六,不过写点入门介绍还是阔以的,特别是那个梗,用rust 写 链表。。。哈哈,我也到时候会给大家实操教学一把,如何不用unsafe,写rust 链表,那的确是老复杂了,还烧脑。
好的,每次放在文章开头的聊天打屁凑字数环节结束,我们废话不多说,先开始今天的内容吧。
按照惯例,如果你是第一次刷到这个文章,不知道前因后果的话,可以点击跳转下面链接的任何一个,从头开始看一遍也可以哟,当作回顾了。
Shell脚本怎么写?(1-2)——Shell 变量的高级用法
Shell脚本怎么写?Linux命令之awk上期(awk是一门语言概述)
好了,下面还是从awk 开始讲起,想必大家看了上期之后,都对awk 有了一个直观的理解,我在这再做一个总结:
awk 是一门完备的编程脚本语言,它按行为粒度去处理数据,完整的awk 脚本 分为 begin {}, {}, end {} 三个部分,begin 和 end 模块仅在开始和结束时执行一次,而中间的模块会处理一行数据执行一次。awk 每次处理一行字符串数据,字符串中默认按照空格划分列,内置变量$1 -- $n 代表这一行的某一列空格分开的字段部分。
awk中有一些常见的内建变量,我们下面先做一个总结:
$n 当前记录的第n个字段,字段间由FS分隔
$0 完整的输入记录
ARGC 命令行参数的数目
ARGIND 命令行中当前文件的位置(从0开始算)
ARGV 包含命令行参数的数组
CONVFMT 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组
ERRNO 最后一个系统错误的描述
FIELDWIDTHS 字段宽度列表(用空格键分隔)
FILENAME 当前文件名
FNR 各文件分别计数的行号
FS 字段分隔符(默认是任何空格)
IGNORECASE 如果为真,则进行忽略大小写的匹配
NF 一条记录的字段的数目
NR 已经读出的记录数,就是行号,从1开始
OFMT 数字的输出格式(默认值是%.6g)
OFS 输出字段分隔符,默认值与输入字段分隔符一致。
ORS 输出记录分隔符(默认值是一个换行符)
RLENGTH 由match函数所匹配的字符串的长度
RS 记录分隔符(默认是一个换行符)
RSTART 由match函数所匹配的字符串的第一个位置
SUBSEP 数组下标分隔符(默认值是/034)
上面的玩意儿是不是看的有点懵逼,咋这么多呢,大家不用触霉头,记住几个常用的就行了,一般日常使用最多的就是 NR, FS,$n 这几个。
然后我们先执行下面awk 命令示例:
awk
'BEGIN{
printf "%4s %4s %4s
%4s %4s %4s %4s %4s
%4s\n",
"FILENAME",
"ARGC",
"FNR",
"FS",
"NF",
"NR",
"OFS",
"ORS",
"RS";
printf "---------------------------------------------\n"}
{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",
FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}' test.txt
看过上期的朋友都知道,这个就是把上面讲的所有的内置变量打印出来,给大家展示一下,由于只打印一次,我们直接写在begin {} 模块中即可。
上面awk 命令执行结果如下:
大家注意,那些看起来没打印出来的其实是空格。。。
然后下面给大家介绍下awk 的使用场景。
- 场景1,提取linux 服务名
大家如果用过linux 系统,肯定知道linux 系统的/etc/passwd文件,保存着这个linux 服务器所有可登录的服务用户名。
具体如下图所示:
然后我们的需求是,快速的获取到每个服务名而剔除掉其它多余的字符串。比如第一行就只留下root, 第二行就留下daemon 等等。
这个例子就很适合使用awk 命令处理,你用sed 的话还需要做字符匹配,sed处理也不是按照行为粒度的等,手动删除就更蠢了。
那如何一句简单的awk 指令就解决呢?
很简单,只需要下面的awk 指令即可:
awk 'BEGIN{
FS=":"
}
{
print $1
}'
/etc/passwd
我们来看看执行结果:
由于分隔符变量使用的还是比较多的,所以awk 提供了入参配置符来进行快捷设置。
上面的命令等价于下面的命令:
awk -F ":" '{print $1}'
/etc/passwd
// 直接使用-F 设置分隔符为“:”
- 场景2:提取某个文件夹所有文件的权限和文件名信息
需求描述:
我们执行在linux 命令中执行ls -al 时,会出现如下结果:
其中有些冗余字段我不需要,我只想留下文件的权限和文件名这两列,并把这两列的内容格式化输出出来。
怎么使用awk 命令完成呢?
聪明的各位读者肯定想到了,
我可以直接如下:
ls -al |
awk '{
print "rights:\t" $1
"\tfilename:\t" $9
}'
// 直接把结果取第一列和第九列不就完了
那我们试试可以吗?
执行下,如下结果:
我们发现,不对啊,有一行数据是错的,这是因为ls -al 执行显示结果的第一行是:
它的格式跟下面我们想要的格式都不一样,如果马虎大意,这不就出bug 了。
那怎么办呢?
我们正确的awk 命令需要使用跳过第一行不处理的判断。
如下是上面需求的正解:
ls -al |
awk '{
if (NR > 1) {
print "rights:\t" $1
"\tfilename:\t" $9
}
}'
// awk是一门语言,别忘了这个话
// 它也有流程控制,if while循环啥都有
// 这才是上面这个需求的正解
好的,今天我们通过实例给大家讲解了awk 的使用场景,其实awk 使用场景真的很多,不局限于字符处理,还有awk 可以做浮点运算,计算器,格式化显示等方方面面,而且它的可定制性很强,语言性比sed grep等命令强大很多。awk还有N多的内置函数,逻辑运算符,流程控制,脚本执行,模块化等,完全不弱于shell 脚本语言。就不再赘述了,大家感兴趣,可以自行学习,一般的确也用不到那么多。
最后的最后,因为有同学留言说想听RUST, 所以今天这篇文章结束后,shell 脚本的介绍就要告一段落了,下一期预告将是Rust 语言入门教程0, 我将会在未来的几个月把rust 语言的语法,所有权,生命周期,rust涉及的方方面面给大家做一个详细的讲解介绍。
如果你觉得文章不错的话,别忘了关注我哟。。。谢谢各位同学。
本文暂时没有评论,来添加一个吧(●'◡'●)