1. awk
可以说在接触了awk之后,我才真正了解到shell的强大之处。先简单的介绍一下awk这是惯例: awk是一种名称奇怪但功能强大的语言。你以为我会告诉你awk是一门独立的语言么?我也才接触awk两三天。所以做的总结必然很基础,但它的功能绝对会让没接触过它的人振奋。原来unix环境下,有如此简便快捷的工具。
1)功能:它是一种样式扫描与处理工具,看到这里你可能对它具体做的事还是一个比较模糊的概念,没关系,继续往下看。
2)调用方式
这个说的实在没意思。
3)awk语法
awk [选项] `命令体` 文件名
选项 –F 指定字符串分隔符,默认是空格或者制表符;
Eg:awk –F: ‘{print $1,$4}’ /etc/passwd
去你的linux命令行去输入这条命令吧,远比我告诉你来得快,很多初学者不理解的是$1,$4.大家一定都知道在shell里$这个运算符的意义:取变量的值。
$# 表示包括$0在内的命令行参数
$0 通常是脚本名称本身
$1 第一个参数
$* 表示整个参数列表
看到这里大家可能就晕了,我不得不提一下,awk是行处理工具,它每次从文本文件里读取一行字符,然后根据-F指定的字符串分隔符来分割字符串,这awk语句内的$1,$4理所当然的就是第1列和第4列。而$0表示整行。
awk流程控制结构
命令:BEGIN{ } 读前处理
{ } 所有行处理
END{ } 读后处理
相信学过英语的都能大致明白awk所谓的流程控制是在干嘛了,没错就是先执行BEGIN{}里的语句,再执行{}里的语句,接着执行END{}里的语句。BEGIN{}代码块在awk处理输入文件之前执行,它是初始化变量的绝佳位置。END{}代码块在文件的所有行处理完之后执行,通常用于最终计算或者打印汇总信息。
Eg:awk –F: ‘BEGIN{print “-------------------”};{print $1};END{print “-------------------”}’ /etc/passwd
这里提及几个比较常用的环境变量
FILENAME 当前文件名
NF 当前记录中的字段数
NR 当前记录数
FNR 当前文件的当前记录数
FS 字段分隔符
OFS 输出字段分隔符
ORS 行输出分隔符
再次说明:awk是一门编程语言,它的语法与C类似,所以if else while for等是毫无疑问的可以在awk里使用的
Eg:#!/bin/bash
#lines是个什么东西呢?字符串,我只能这样告诉你,是END{}代码块执行的结果
lines=$(awk ‘BEGIN{FS=”:”}{ary[$7]++}END{for(i in ary) print ary[i],i}’ /etc/passwd)
arr=(${lines[@]})
i=${#arr[*]}
echo ${arr[*]}
我想我得解释一下了中间的awk 这条语句,提一下shell里是没有类型声明的。
FS=”:” 指定:为字符串分隔符
Ary[$7] $7是什么,是字符串,以字符串作为数组下标,让我不得不联想到了map<key,value> 我只能以这样一种方式来看待它,不然实在让我…
这个shell脚本的功能是统计当前linux系统下每一种shell环境分别有多少个用户使用。大家还是去跑跑吧。大家可能疑惑不解的是数组相关的问题,当然我会整理一下。
来看看下面的shell会对理解上面的代码有帮助
#!/bin/bash
line=$”ab cd ef gh”
echo $line
arr=${line[*]}
echo $arr
echo ${arr[1]};
运行结果:
ab cd ef gh
ab cd ef gh
我再改改上面的代码
#!/bin/bash
line=$”ab cd ef gh”
echo $line
arr=(${line[*]})
echo $arr
echo ${arr[1]};
运行结果:
ab cd ef gh
ab
cd
加了()之后,字符串被顺利的转换为了数组。给大家说一下shell中数组的用法
取数组中第n个元素valuen=${arr[n]}
取数组中的全部元素echo ${arr[@]} 或者 ${arr[*]}
取数组元素的个数 length=${#arr[*]}
取数组中单个元素的长度 lengthn=${#arr[n]}
我也试了一下将字符串中间的分隔符改为,.或者: 都不能像空格那样成功的转换为数组。
当然awk是提供了一个函数来完成这项功能的split(字符串,数组,字段分隔符):它可以讲字符串拆分为词,然后保存在数组中。