Ubuntu Pattern正则表达式匹配所指定
Ubuntu Pattern已被广泛应用但是也在不断的更新,这里介绍Ubuntu Pattern安装设置使用,帮助大家安装更新Ubuntu Pattern系统。选择符合指定条件的记录 Ubuntu Pattern { Action }为awk中最主要的语法. 若某Ubuntu Pattern之值为真则执行它后方的 Action. awk中常使用"关系表达式" (Relational Expression)来当成 Ubuntu Pattern.
awk 中除了>, <, ==, != ,...等关系运算符( Relational Operators )外,另外提供 ~(match),!~(Not Match) 二个关系运算符. 利用这两个运算符, 可判断某字符串是否包含能匹配所指定正则表达式的子字符串. 由于这些特性, 很容易使用awk来编写需要字符串比对, 判断的程序. 组装部门员工调薪5%,(组装部门员工之ID以"A"开头) 所有员工最后之薪资率若仍低于100, 则以100计. 编写awk程序打印新的员工薪资率报表.
[分析 ] : 这个程序须先判断所读入的数据行是否合于指定条件, 再进行某些动作.awk中 Ubuntu Pattern { Actions } 的语法已涵盖这种 " if ( 条件) { 动作} "的架构. 编写如下之程序, 并取名 adjust1.awk $1 ~ /^A.*/ { $3 *= 1.05 } $3<100 { $3 = 100 } { printf("%s %8s %d"n", $1, $2, $3)} 执行下列命令 : $awk -f adjust1.awk emp.dat
结果如下 : 屏幕出现 :
A125 Jenny 105 A341 Dan 115 P158 Max 130 P148 John 125 A123 Linda 100
说 明 : awk的工作程序是: 从数据文件中每次读入一个数据行, 依序执行完程序中所有的 Ubuntu Pattern{ Action }指令:
$1~/^A.*/ { $3 *= 1.05 } $3 < 100 { $3 = 100 } {printf("%s %8s %d"n",$1,$2,$3)}
再从数据文件中读进下一笔记录继续进行处理. 第一个 Ubuntu Pattern { Action }是: $1 ~ /^A.*/ { $3 *= 1.05 } $1 ~ /^A.*/ 是一个Ubuntu Pattern, 用来判断该笔数据行的第一栏是否包含以"A"开头的子字符串. 其中 /^A.*/ 是一个Regular Expression, 用以表示任何以"A"开头的字符串. (有关 Regular Expression 之用法 参考 附录 E ).
Actions 部分为 $3 *= 1.05 $3 *= 1.05 与 $3 = $3 * 1.05 意义相同. 运算子"*=" 之用法则与 C 语言中一样. 此后与 C 语言中用法相同的运算子或语法将不予赘述. 第二个 Ubuntu Pattern { Actions } 是: $3 <100 {$3 = 100 } 若第三栏的数据内容(表薪资率)小于100, 则调整为100. 第三个 Ubuntu Pattern { Actions } 是: {printf("%s %8s %d"n",$1, $2, $3 )} 省略了Ubuntu Pattern(无条件执行Actions), 故所有数据行调整后的数据都将被印出.
awk 中数组
awk程序中允许使用字符串当做数组的下标(index). 利用这个特色十分有助于资料统计工作.(使用字符串当下标的数组称为Associative Array) 首先建立一个数据文件, 并取名为 reg.dat. 此为一学生注册的资料文件; 第一栏为学生姓名, 其后为该生所修课程.
Mary O.S. Arch. Discrete Steve D.S. Algorithm Arch. Wang Discrete Graphics O.S. Lisa Graphics A.I. Lily Discrete Algorithm
awk中数组的特性 使用字符串当数组的下标(index). 使用数组前不须宣告数组名及其大小. 例如: 希望用数组来记录 reg.dat 中各门课程的修课人数. 这情况,有二项信息必须储存:
(a) 课程名称, 如: "O.S.","Arch.".. ,共有哪些课程事先并不明确.
(b)各课程的修课人数. 如: 有几个人修"O.S."
在awk中只要用一个数组就可同时记录上列信息. 其方法如下: 使用一个数组 Number[ ] : 以课程名称当 Number[ ] 的下标. 以 Number[ ] 中不同下标所对映的元素代表修课人数.
例如: 有2个学生修 "O.S.", 则以 Number["O.S."] = 2 表之. 若修"O.S."的人数增加一人,则 Number["O.S."] = Number["O.S."] + 1 或 Number["O.S."]++ . 如何取出数组中储存的信息 以 C 语言为例, 声明 int Arr[100]; 之后, 若想得知 Arr[ ]中所储存的数据, 只须用一个循环, 如 : for(i=0; i<100; i++) printf("%d"n", Arr[i]);
即可. 上式中: 数组 Arr[ ] 的下标 : 0, 1, 2,..., 99 数组 Arr[ ] 中各下标所对应的值 : Arr[0], Arr[1],...Arr[99] 但 awk 中使用数组并不须事先宣告. 以刚才使用的 Number[ ] 而言, 程序执行前, 并不知将来有哪些课程名称可能被当成 Number[ ] 的下标.
awk 提供了一个指令, 藉由该指令awk会自动找寻数组中使用过的所有下标. 以 Number[ ] 为例, awk将会找到 "O.S.", "Arch.",... 使用该指令时, 须指定所要找寻的数组, 及一个变量. awk会使用该的变量来记录从数组中找到的每一个下标. 例如
for(course in Number){....} 指定用 course 来记录 awk 从Number[ ] 中所找到的下标. awk每找到一个下标时, 就用course记录该下标之值且执行{....}中之指令. 藉由这个方式便可取出数组中储存的信息.
[ 范例 : ] 统计各科修课人数,并印出结果. 建立如下程序,并取名为 course.awk: { for( i=2; i <= NF; i++) Number[$i]++ } END{for(course in Number) printf("%10s %d"n", course, Number[course] )}
执行下列命令 : $awk -f course.awk reg.dat
执行结果如下 :
Graphics 2 O.S. 2 Discrete 3 A.I. 1 D.S. 1 Arch. 2 Algorithm 2
这程序包含二个Ubuntu Pattern { Actions }指令. { for( i=2; i <= NF; i++) Number[$i]++ } END{for(course in Number) printf("%10s %d"n", course, Number[course] )} 第一个Ubuntu Pattern { Actions }指令中省略了Ubuntu Pattern 部分. 故随着每笔数据行的读入其Actions部分将逐次无条件被执行.
以awk读入第一笔资料 " Mary O.S. Arch. Discrete" 为例, 因为该笔数据 NF = 4(有4个字段), 故该 Action 的for Loop中i = 2,3,4. i $i 最初 Number[$i] Number[$i]++ 之后 i=2时 $i="O.S." Number["O.S."]的值从默认的0,变成了1 ;i=3时 $i="Arch." Number["Arch."]的值从默认的0,变成了1 ;同理,i=4时 $i="Discrete" Number["Discrete"]的值从默认的0,变成了1 ;