速查笔记(Linux Shell编程上)(3)


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 域变量也可以作为数组的下标.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyfgfd.html