awk:是一种很方便的数据处理的编程语言,用于数据分析并生成报告
基本格式:
awk [options] ‘program’ file
awk 可选参数 ‘可执行脚本代码’ 文件
先举个?,NoZuoNoDie组合练习生的文件:NoZuoNoDie.csv
name | practiceTtime | ranking |
---|---|---|
he | 5 | 3 |
wei | 12 | 5 |
bai | 10 | 2 |
sa | 4 | 4 |
jia | 7 | 1 |
现在想找出排名前三的练习生
解释下:
-
第一句是输出这个文件的所有内容,类似于cat filename。awk执行print $0这条命令:输出$0, $0代表当前行,所以把所有行都输出了
-
第二句是输出前三名的命令啦
- 因为平时用CSV文件比较多,就用CSV文件举例,因此需要可选参数-F 指定分隔符为逗号,默认的分隔符为空格和制表符
- $符号后边的数字代表第几行,$3 <= 3,第三行小于等于4
- {print $1} 输出第一行,也就是姓名
- 最后是文件名
接下来正式开始,以下都是我实践后,直接上截图,然后解释每句,语句不能粘贴,大家一定要多动手,自己手动敲一遍,才会更深刻哦(才不会说是因为我懒(ーー゛)
打印
1. 打印每一行
- awk ‘{print}’ NoZuoNoDie.csv
将所有的输入打印到标准输出- awk ‘{print $0}’ NoZuoNoDie.csv
$0代表一整行,所以输出一整行
2.打印某些字段
截图按照顺序为1、2、3
- 第1个输出文件的全部内容,
- 2要输出第1、2行,但因为默认分隔符是空格、制表符,所以只有一行,第二行是空,
- 3呃,和2一模一样,省略
- 4指定了分隔符,输出第1、2行,看起来好乱,1、2行之间加个制表符,看起来会很好
- 所以5,在{print $1 “\t” $2}第1、2行输出的中间加入了制表符\t,要用双引号哦
- 纠正个问题,在输出第一行第二行之间加上逗号,如下图,会自动填充看起来应该是空格,但是加制表符看起来更好看啦
3. NF
- NF是awk的內建变量,计算当前输入行的字段数量
- 第一行输出了文件行数,1输出第1行内容,1输出第1行内容,1输出第1行内容,NF输出第三行内容,这个文件有3行,此时NF值为3,所以$NF输出第三行
- 第二个例子依次输出行数,第一行内容,第三行内容,第二行内容
4. 计算和打印
- 输出全部内容,再输出第2行和第三行相乘的值
- 看着不好看,加个制表符看看,不好看pass
- 同1
- NR代表行号,输出行号,全部内容,和$2 * $3,看起来好一点
- 只输出行号,name行,$2*$3
- 为了更好看,可以任意拼接字符串,如6、7,注意:‘s的引号,需要用反斜杠哦
5. 精美的输出
- print用于简单快速的输出,printf可以输出任何种类
- %s代表第一个值以字符串形式打印,%.2f第二个值按照数值格式打印,且带2位小数。
- 末尾的\n是换行,printf不会自动换行,需要自己加,第二个例子,不加换行的效果
- 其他:
- %-8s左对齐输出,占用8个字符
- %5.2f,以带有2位小数点的数值格式打印,数字至少占用6个字符宽度
- 排序
awk -F ',' '{printf "%s, %s\n", $3, $1}' NoZuoNoDie.csv | sort -n
6. 比较、判断
-
大于>、小于<、等于==、和&&、或||、非 !
-
验证
-
BEGIN、END
-
7. 计算
8. 內建函数
length计算字符个数
awk -F ',' '{print $1, length($1) }' NoZuoNoDie.csv
out:
name 4
he 2
wei 3
bai 3
sa 2
jia 3
(以下偷懒了,实在是太晚啦,有空补==。。。
9. 流程控制语句
- if else
$2 > 6 { n = n + 1; pay = pay + $2 * $3 } END { if (n > 0) print n, "employees, total pay is", pay, "average pay is", pay/n else print "no employees are paid more than $6/hour" }
- while
{ 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) }
10. 数组
{ line[NR] = $0 } # remember each input line
END { i = NR # print lines in reverse order
while (i > 0) {
print line[i]
i=i-1 }
}
11. 其他
- 输入行的总行数
END { print NR } - 打印第 10 行
NR == 10 - 打印每一个输入行的最后一个字段 { print $NF }
- 打印最后一行的最后一个字段
{ field = $NF }
END { print field } - 打印字段数多于 4 个的输入行 NF > 4
- 打印最后一个字段值大于 4 的输入行 $NF > 4
- 打印所有输入行的字段数的总和 { nf = nf + NF }
END { print nf } 8. 打印包含 Beth 的行的数量
/Beth/ { nlines = nlines + 1 }
END { print nlines } - 打印具有最大值的第一个字段, 以及包含它的行 (假设 $1 总是 正的) $1 > max { max = $1; maxline = $0 }
END { print max, maxline } - 打印至少包含一个字段的行 NF > 0
- 打印长度超过 80 个字符的行 length($0) > 80
- 在每一行的前面加上它的字段数 { print NF, $0 }
- 打印每一行的第 1 与第 2 个字段, 但顺序相反 { print $2, $1 }
- 交换每一行的第 1 与第 2 个字段, 并打印该行
{ temp = $1; $1 = $2; $2 = temp; print } - 将每一行的第一个字段用行号代替 { $1 = NR; print }
- 打印删除了第 2 个字段后的行
{ $2 = “”; print } - 将每一行的字段按逆序打印
{ for (i = NF; i > 0; i = i - 1) printf("%s “, $i)
printf(”\n")
} - 打印每一行的所有字段值之和
{ sum = 0
for (i = 1; i <= NF; i = i + 1) sum = sum + $i
print sum
} - 将所有行的所有字段值累加起来
{ for (i = 1; i <= NF; i = i + 1) sum = sum + $i }
END { print sum } - 将每一行的每一个字段用它的绝对值替换
{ for (i = 1; i <= NF; i = i + 1) if ($i < 0) i=−i = -i=−i
print
}