1. 执行方式:
1) awk 'pattern' filename 如awk '/Mary/' employees
2) awk '{action}' filename 如awk '{print $1}' employees
3) awk 'pattern {action}' filename 如awk '/Mary/ {print $1}' employees
注: 模式/Mary/对action的作用范围是从其后面的第一个左花括号开始,到第一个右花括号结束. 其后的pattern将不会影响前面的action.
2. 内置变量:
$0: 表示一整行(相当于数据库中一条记录).
NR: 当前行号.
NF: 当前记录的域(相当于数据库中的字段)数量
RS: 行分隔符(缺省为回车).
FS: 域分隔符,缺省为\t. awk -F: '{print $1,$2,$3}' employees 这里FS等于":".
OFS:输出域分隔符, awk -F: '{print $1,$2,$3}' employees 这里OFS等于" "空格, 因为在$1和$2之间是空格分开的.
ARGC: 命令行参数的数量.
ARGV: 命令行参数数组.
ENVIRON: 从shell传递来的包含当前环境变量的数组.
ERRNO: 错误号.
FILENAME: 当前的输入文件名.
3. 格式化输出:
转义码:
\b: Backspace.
\n: 换行.
\r: 回车.
\t: 制表符.
格式化说明符:
%c: 单个ASCII字符.
%d: 十进制数字.
%e: 科学记数法表示的数字.
%f: 浮点数.
%o: 八进制数字.
%s: 打印字符串.
%x: 十六进制数字.
-: 表示左对齐,如%-15d, 在十进制数字的后面会有一些空格,同时该数字是左对齐的. %+15d或%15d表示右对齐,当数字不足15位的时候.
#: 如%#o或%#x, 会在八进制的数字前面加入0,十六进制前加0x.
4. 操作符:
~: 匹配运算符. 如awk '$1~/Mary/' employees, 表示第一个域($1)中包含Mary的被打印, 如果其他域包含,第一个域没有,则仍然视为无效.
!~: 不匹配运算符. 如awk '$1!~/Mary/' employees, 表示第一个域($1)中不包含Mary的被打印, 如果其他域包含,第一个域没有,则仍然视为有效.
<,>,<=,>=,!=,==: 关系运算符. awk '$3>5000 {print $3}' datafile
cond ? expr1 : expr2 条件表达式 awk '{max = $1 > $2 ? $1 : $2; print max}' datafile
=,+=,-=,*=,/=,%=: 赋值运算符.
-,+,*,/,%,^(x^y[乘方]): 数学运算符.
&&, ||, !: 逻辑运算符.
,: 表示范围, awk '/Tom/,/Mary/' datafile 其规则可参照sed中逗号运算符.
5. 选项:
-F: 指定特定的分隔符,而不是缺省的\t, 如-F:,这里分隔符是":".
6. awk编程:
1) BEGIN: 其后紧跟着动作块, 该块将会在任何输入文件被读入之前执行, 如一些初始化工作, 或者打印一些输出标题.
awk 'BEGIN{FS=":"; OFS="\t";ORS="\n\n"} {print $1,$2,$3}' file
即使输入文件不存在, BEGIN块动作仍然会被执行.
2) END: 其后也紧随动作块, 该动作模块将在整个输入文件处理完毕之后被处理, 但是END需要有文件名的输入.
awk 'END {print "The end\n"} filename.
3) 输入输出重新定向:
awk 'BEGIN {print "Hello" > "newfile"}' datafile 文件名一定要用双引号扩起来, > 如果文件存在,则清空后重写新文件.
awk 'BEGIN {print "Hello" >> "newfile"}' datafile 文件名一定要用双引号扩起来, > 如果文件存在, 则在文件末尾追加写入.
awk 'BEGIN {getline name < "/dev/tty"; print name}' getline是awk的内置函数, 就像C语言的gets, 将输入赋值给name变量.
4) system函数可以执行shell中的命令,这些命令必须用双引号扩起.
awk 'END { system("clear"); system ("cat " FILENAME)}' filename
5) 条件语句:
if (expr) { stat; } else { stat; }
if (expr) { stat; } else if { stat; } else { stat; }
awk '{ if ($7 <= 2) { print "less than 2", $7 } else if ($7 <= 4) { print "less than 4", $7 } else { print "the others", $7 } }' datafile
6) 循环语句:
while (expr) { stat; }
for (i = 1; i <= NF; i++) { stat; }
break;
continue;
exit(exitcode); awk 将退出. 退出后的$?将会是这里的exitcode.
next; 读取下一条记录. awk '{ if ($7 == 3) { next } else { print $0 }}' datafile 将不会输出$7等于3的记录.
7) 数组:
awk的数组和pl/sql中数组有些类似, 都是通过哈希表来实现的,其下标可以是数字, 也可以是字符串.
awk '{name[x++]=$3};END{for(i = 0; i < NR; i++) { print i, name[i]}}' employees
awk '{id[NR]=$3};END{for (x = 1; x <= NR; x++) { print id[x]} }' employees
awk '/^Tom/{name[NR]=$1}; END{for (i in name) { print name[i]}}' employees 特殊的for语句
awk '/Tom/{count["tom"]++}; /Mary/{count["mary"]++}; END{print "count[tom] = ",count["tom"]; print "count[mary] = ", count["mary"]}' employees
awk '{count[$2]++};END{for (name in count) {print name,count[name]}}' datafile 域变量也可以作为数组的下标.
速查笔记(Linux Shell编程上)(3)
内容版权声明:除非注明,否则皆为本站原创文章。