专业的编程技术博客社区

网站首页 > 博客文章 正文

Shell脚本怎么写?Linux命令之awk下期(awk日常使用)

baijin 2024-08-14 12:41:41 博客文章 8 ℃ 0 评论

大家好呀,今天是周三,早点下班给大家肝文章的awk 下期,顺便给大家做个预告,后面会开新的一个专题,讲一下Rust 这个编程语言的知识和入门(咱也蹭蹭热度),我用Rust 也有两年多的时间了,虽然没有用c++ 那么六六六,不过写点入门介绍还是阔以的,特别是那个梗,用rust 写 链表。。。哈哈,我也到时候会给大家实操教学一把,如何不用unsafe,写rust 链表,那的确是老复杂了,还烧脑。

好的,每次放在文章开头的聊天打屁凑字数环节结束,我们废话不多说,先开始今天的内容吧。

按照惯例,如果你是第一次刷到这个文章,不知道前因后果的话,可以点击跳转下面链接的任何一个,从头开始看一遍也可以哟,当作回顾了。

Shell脚本怎么写?(0)

Shell脚本怎么写?(1)——Shell 变量类型和定义

Shell脚本怎么写?(1-2)——Shell 变量的高级用法

Shell脚本怎么写?之 Shell脚本中的流程控制(1)

Shell脚本怎么写?之 Shell脚本中的流程控制(2)

Shell脚本怎么写?之简单Shell 脚本编写实践

Shell脚本怎么写?之简单Shell 脚本函数和模块

Shell脚本怎么写?Linux命令三剑客之sed命令

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. 场景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 设置分隔符为“:”
  1. 场景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涉及的方方面面给大家做一个详细的讲解介绍。

如果你觉得文章不错的话,别忘了关注我哟。。。谢谢各位同学。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表