刚刚进入工作一个多月了,发现工作环境需要大量使用linux命令,趁着国庆假期补补课。 参考: https://awk.readthedocs.io/en/latest/chapter-one.html
1.awk程序结构 pattern{action} awk的基本操作是一行一行扫描输入,搜索匹配模式的行,执行动作后进行下一行的读取。
1) A 数学 80 2) B 语文 90 3) C 英语 87对于上述的表数据,
$4 == 90 {print $2}将打印出第4个字段为90的名字,B。 也可以在多个文件上执行这些命令。
awk '$3==0{print $2}' file1 file2当程序命令较短时,选择使用单引号包装。当程序过长时,则可将其写入到文件中。
awk -f progfile optional list of input files #-f:表示从指定文件中获取程序小结 awk命令默认是读取文件的一行内容,并根据空格和制表符分成多个字段,其中一个字段是不包含任何空格或者制表符的连续字符序列。其中$0为整行字符,$1为第一个字段,$2为第二个字段。
{print } #打印每一行内容 #or {print $0}2.awk的简单输出 利用print打印多个字段,
{print $1, $3}打印第一个和第三个字段,中间用空格分离,最后用回车符号结尾。如下所示,
1) 数学 2) 语文 3) 英语字段数量 awk命令会对一行的多少个字段数进行计数,并将其存储在一个叫做NF的变量中。
{print NF, $1, $NF} #打印字段数目,以及第一个和最后一个字段字段的计算
{print $1, $2*$3}行号 变量NR,存储行的计数。
{print NR, $0}能够为每一行加上行号.
添加内容 双引号中内容将添加到输出内容中。
{print "total pay for", $1, "is","$2*$3"}格式化输出 若要严格按照需要的格式化输出,则需要使用printf语句。 printf语句形式:
printf(format, value1, value2, ... valuen)如:
{printf("total pay for %s is %.2f\n", $1, $2*$3)}其中%s表示以字符串方式打印第一个字段,第二个以数字打印,并保留小数点后2位数字,结尾需要回车来创建行。
{printf("%-8s %6.2f\n", $1, $2*$3)}第一个规格%-8s,将第一个字段在8个字符宽度的字段中左对齐输出。第二个规格%6.2f将字段2以数字形式,保留小数点后两位,以6字符宽度的字段中进行输出。
awk '{ print("%6.2f, %s\n", )}'递增方式打印 排序方式输出
awk '{printf("%6.2f %s\n",$2*$3, $0)}' filename |sort将awk的输出通过管道传输给sort命令,按照$2*$3字段递增方式排序。
3.数据选择
$2*$3>50 {printf("$%.2f for %s\n", $2*$3, $1)} #根据>50的条件筛选字段 $1 == "Susie" #根据==号筛选字符串模式组合,通过括号和&&,||,!来对模式进行组合。 两个条件都满足的打印一次
$2 >= 4 || $3 >= 20打印既不满足$2<4也不满足$3<20的行
!($2 < 4 && $3 < 20)数据验证
'NF!=3 {print $0, "number is not equal to 3"}'BEGIN与END BEGIN匹配第一个输入文件第一行之前的位置,END用于匹配最后一个文件最后一行的位置。 如下,使用Begin匹配一个标题: 程序动作部分可加多个语句,但是需要用分行隔开。 普通的print是打印当前输入行,但是print ""则是打印一个空行。
BEGIN {print "Name RATE HOUR"; print ""} {print}4.数值计算 统计第3个字段大于15的值,如果不加END,每读取一行就打印一次计数,加END打印最后的一次计数。
$3 >15 {emp = emp + 1} END {print emp, "more than 15"}计算行数
NR {print NR, "numbers"}处理文本
$2 > maxscore {maxscore=$4; maxname=$2} END {print "maxscore is",maxscore,"for",maxname}程序中变量maxscore保留着数字,maxname保留着字符串。
字符串拼接
{names=names $2 " "} END {print names}首先初始化一个names,为空字符串,然后再使用第一行的第二个字段和空格进行拼接。最后打印所有的字符串。其中用于保存字符串变量names的默认初始值为空字符串,不需要显示初始化。
打印最后一行
{last = $0} END {print last}测试了一下,$0也能打印出最后一行的结果。
END {print $0}length(…) 统计字符串长度内置函数
{print $1, legnth($1)}统计行数,单词书(字段数),字符数
{nc = nc + length($0) +1 #加了每行的换行符 nw = nw + NF} END {print NR, "lines,", nw "words," nc, "characters"}控制语句 if-else语句,需要在action中使用。
$2>6,{n=n+1;pay=pay+$2*$3} END {if(n>0) print n else print "0" }可在语句中使用逗号将长语句进行截取。 while
# interest1 - 计算复利 # 输入: 钱,利率,年数 # 输出: 复利值 { i=1 while (i<=$3) { printf("\t %.2f\n",$1*(1+$2)^i) i=i+1 } }for循环 循环体只是一句语句,因此不需要用大括号来包围它。
{ for(i=1;i<=$3;i=i+1) printf("\t%.2f\n",$1*(1+$2)^i) }数组 写到统一行记得用;隔开
#逆序打印输入 {line[NR]=$0} END { i=NR while(i>0){ print line[i] i=i-1 } }改成for循环,同一行记得用分号隔开啊,今天的就到这里了。
{line[NR]=$0} END {for(i=NR;i >0;i--) print line[i]}