丽水微信网站建设报价,wordpress 更改ip,淄博建网站多少钱,怎么优化WordPress主题文本处理的工作中#xff0c;awk的数组是必不可少的工具#xff0c;在这里#xff0c;同样以总结经验和教训的方式和大家分享下我的一些学习心得#xff0c;如有错误的地方#xff0c;请大家指正和补充。 awk的数组#xff0c;一种关联数组#xff08;Associative Array…文本处理的工作中awk的数组是必不可少的工具在这里同样以总结经验和教训的方式和大家分享下我的一些学习心得如有错误的地方请大家指正和补充。 awk的数组一种关联数组Associative Arrays下标可以是数字和字符串。因无需对数组名和元素提前声明也无需指定元素个数 所以awk的数组使用非常灵活。 首先介绍下几个awk数组相关的知识点 1建立数组 array[index] value 数组名array下标index以及相应的值value。 复制代码 2读取数组值 { for (item in array) print array[item]} # 输出的顺序是随机的 {for(i1;ilen;i) print array[i]} # Len 是数组的长度 复制代码 3多维数组array[index1,index2,……]SUBSEP是数组下标分割符默认为“\034”。可以事先设定SUBSEP也可以直接在SUBSEP的位置输入你要用的分隔符如 awk BEGIN{SUBSEP:;array[a,b]1;for(i in array) print i} a:b awk BEGIN{array[a:b]1;for(i in array) print i} a:b 复制代码 但有些特殊情况需要避免如 awk BEGIN{ SUBSEP: array[a,b:c]1 # 下标为“a:b:c” array[a:b,c]2 #下标同样是“a:b:c” for (i in array) print i,array[i]} a:b:c 2 #所以数组元素只有一个。 复制代码 4删除数组或数组元素 使用delete 函数 delete array #删除整个数组 delete array[item] # 删除某个数组元素item 复制代码 5 排序awk中的asort函数可以实现对数组的值进行排序不过排序之后的数组下标改为从1到数组的长度。在gawk 3.1.2以后的版本还提供了一个asorti函数这个函数不是依据关联数组的值而是依据关联数组的下标排序即asorti(array)以后仍会用数字1到数组长度来作为下标但是array的数组值变为排序后的原来的下标除非你指定另一个参数如:asorti(a,b)。非常感谢lionfun对asorti的指正和补充 echo aa bb aa bb cc |\ awk {a[$0]}END{lasorti(a);for(i1;il;i)print a[i]} aa bb cc echo aa bb aa bb cc |\ awk {a[$0]}END{lasorti(a,b);for(i1;il;i)print b[i],a[b[i]]} aa 2 bb 2 cc 1 复制代码 下面说awk数组的实际应用。 1. 除去重复项, 这个不多说, 只给出代码 awk !a[$0] file(s) awk !($0 in a){a[$0];print} file(s) 复制代码 另一种
http://bbs.chinaunix.net/thread-1859344-1-1.html 2. 计算总数sum如 awk {name[$0]$1};END{for(i in name) print i, name[i]} 再举个例子 echo aaa 1 aaa 1 ccc 1 aaa 1 bbb 1 ccc 1 |awk {a[$1]$2}END{for(i in a) print i,a[i]} aaa 3 bbb 1 ccc 2 复制代码 3. 查看文件差异。 cat file1 aaa bbb ccc ddd cat file2 aaa eee ddd fff 复制代码 1 合并file1和file2除去重复项 awk NRFNR{a[$0]1;print} #读取file1建立数组a下标为$0并赋值为1然后打印 NRFNR{ #读取file2 if(!(a[$0])) {print } #如果file2 的$0不存在于数组a中即不存在于file1则打印。 } file1 file2 aaa bbb ccc ddd eee fff 复制代码 2 提取文件1中有但文件2中没有 awk NRFNR{a[$0]1} #读取file2建立数组a下标为$0并赋值为1 NRFNR{ #读取file1 if(!(a[$0])) {print } #如果file1 的$0不存在于数组a中即不存在于file2则打印。 } file2 file1 bbb ccc 复制代码 另
http://bbs.chinaunix.net/viewthr ... page1#pid15547885 4. 排序 echo a 1 0 b 2 10 8 100 | awk {a[$0]$0} #建立数组a下标为$0赋值也为$0 END{ lenasort(a) #利用asort函数对数组a的值排序同时获得数组长度len for(i1;ilen;i) print i \ta[i] #打印 } 1 0 2 1 3 2 4 8 5 10 6 100 7 a 8 b 复制代码 5. 有序输出采用index in array的方式打印数组值的顺序是随机的如果要按原序输出则可以使用下面的方法
http://bbs2.chinaunix.net/viewthread.php?tid1811279 awk {a[$1]$2 c[j]$1} END{ for(m0;mj;m)print c[m],a[c[m]] } 复制代码 6. 多个文本编辑这里主要指的是待处理的文本之间的格式上有区别如分隔符不同或是待处理文本需提取的信息的位置不同如不同的列或行。 例1 cat file1 g1.1 2 g2.2 4 g2.1 5 g4.1 3 cat file2 g1.1 2 g1.2 3 g4.1 4 cat file3 g1.2 3 g5.1 3 复制代码 要求输出 g1.1 2 2 - g1.2 - 3 3 g2.2 4 - - g2.1 5 - - g4.1 3 4 - g5.1 - - 3 复制代码 实现代码如下 awk {a[ARGIND $1]$2 # ARGIND是当前命令行文件的位置从0开始将它和第一列的value作为下标建立数组a。 b[$1] #将第一列的value作为下标建立数组b目的是在读完所有文件之后能得到第一列value的uniqe-list。 } END{ for(i in b) { printf i for(j1;jARGIND;j) printf %s , a[j i]?a[j i]:- #此时的ARGIND值为3. print } } file1 file2 file3 复制代码 这里是利用awk的内置变量ARGIND来处理完成对文件的处理。关于ARGINDARGVARGC的使用大家可以参考
http://bbs.chinaunix.net/viewthr ... 0335fromfavorites
。 当然我们也可以利用另外一个内置变量FILENAME来完成相同的任务大家可以先想想怎么写如下 awk {a[FILENAME $1]$2;b[$1];c[FILENAME]}END{for(i in b) {printf i ;for(j in c) printf %s , a[j i]?a[j i]:-;print}} file1 file2 file3 复制代码 例2对上面的数据的格式稍作改动每个文件的分隔符都一样的情况但输出要求不变 cat file1 g1.1|2 g2.2|4 g2.1|5 g4.1|3 cat file2 g1.1#2 g1.2#3 g4.1#4 cat file3 g1.23 g5.13 复制代码 实现代码如下 awk {a[ARGIND $1]$2 b[$1] } END{ for(i in b) { printf i for(j2;jARGIND;j2) printf %s , a[j i]?a[j i]:- # 由于FS的设置也是有对应ARGIND值所以对ARGIND稍作改动。 print } } FS| file1 FS# file2 FS file3 # 对每个文件分别设置FS的值。 复制代码 因为这个例子的数据比较简单我们也可以在BEGIN模块中完成对FS值设置如下 awk BEGIN{FS[|#]}{a[ARGIND $1]$2; b[$1]}END{for(i in b) {printf i ;for(j1;jARGIND;j) printf %s , a[j i]?a[j i]:-; print }} file1 file2 file3 复制代码 利用FILENAME 同样可以解决问题 awk FILENAMEfile1{FS|} # 设置FS FILENAMEfile2{FS#} #设置FS FILENAMEfile3{FS} #设置FS # 稍显繁琐不过一目了然 {$0$0} #使FS生效。 {a[ARGIND $1]$2; b[$1]} END{ for(i in b) {printf i ; for(j1;jARGIND;j) printf %s , a[j i]?a[j i]:-; print } } file1 file2 file3 复制代码 推荐一个关于数组处理文件的帖子
http://www.chinaunix.net/jh/24/577044.html 里面有不少例子供大家学习。 7. 文本翻转或移位二维或多维数组的应用 例1 Inputfile 1 2 3 4 5 6 2 3 4 5 6 1 3 4 5 6 1 2 4 5 6 1 2 3 Outputfile 4 3 2 1 5 4 3 2 6 5 4 3 1 6 5 4 2 1 6 5 3 2 1 6 awk { if (max_nf NF) max_nf NF # 数组第一维的长度 max_nr NR # 数组第二维的长度 for (x 1; x NF; x) vector[x, NR] $x #建立数组vector } END { for (x 1; x max_nf; x) { for (y max_nr; y 1; --y) printf(%s , vector[x, y]) printf(\n) } } 复制代码 例2来自
http://bbs.chinaunix.net/viewthr ... page1#pid13339226 有两个文本a和b要求输出c文本合并的规则是按照第一行的headline按字母顺序合并文本a和b空缺按“0”补齐。 cat a.txt a b c d 1 2 9 7 4 5 8 9 5 3 6 1 cat b.txt a e f d g 9 2 4 7 3 4 3 7 9 4 cat c.txt a b c d e f g 1 2 9 7 0 0 0 4 5 8 9 0 0 0 5 3 6 1 0 0 0 9 0 0 7 2 4 3 4 0 0 9 3 7 4 复制代码 下面我们来参看并解读下Tim大师的代码 awk FNR1{ #FNR1即a和b文本的第一行这个用的真的很巧妙。 for(i1;iNF;i){ b[i]$i #读取文本的每个元素存入数组b c[$i]} #另建立数组c并统计每个元素的个数 next #可以理解为读取FNR!1的文本内容。 } {k # 统计除去第一行的文本行数 for(i1;iNF;i)a[k,b[i]]$i #利用一个二维数组来保持每个数字的位置 kb[i]可以理解为每个数字的坐标。 } END{ lasorti(c) #利用asorti函数对数组的下标进行排序并获取数组长度即输出文件的列数(NF值) for(i1;il;i)printf c[i] # 先打印第一行相当于headline。 print for(i1;ik;i){ for(j1;jl;j)printf a[i,c[j]]?a[i,c[j]] :0 # 打印二维数组的值。 print } } a.txt b.txt 复制代码 8. 选择性打印 打印某个关键字前几行以3行为例 seq 20 |awk /\10\/{for(iNR-3;iNR;i)print a[i%3];exit}{a[NR%3]$0} 7 8 9 复制代码 利用NR取余数建立数组这是一种非常高效的代码。 9. 通过split函数建立数组数组的下标为从1开始的数字。 split(s, a [, r]) # sstring aarray name[,r]regular expression。 echo abcd |awk {lensplit($0,a,);for(i1;ilen;i) print a[i] a[i];print length len} a[1] a a[2] b a[3] c a[4] d length 4 复制代码 10 awk数组使用的小技巧和需要避免的用法 1 嵌套数组 awk BEGIN{a[1]3;b[1]1;print a[b[1]]} 3 复制代码 2 下标设为变量或函数 awk BEGIN{s123;a[substr(s,2)]substr(s,1,1);for(i in a)print index : i\nvalue : a[i]} index : 23 value : 1 复制代码 3 不可以将数组名作为变量使用否则会报错 awk BEGIN{a[1] 3; delete a;a3;print a} #即使你已经使用了delete函数。 awk: fatal: attempt to use array a in a scalar context 复制代码 4 数组的长度 length(array) 复制代码 5 match 函数也可以建立数组你知道么 版本要求高于gawk 3.1.2 echo foooobazbarrrrr | gawk { match($0, /(fo).(bar*)/, arr) #匹配到的部分自动赋值到arr中下标从1开始 print arr[1], arr[2] print arr[1, start], arr[1, length] #二维数组arr[index,start]值RSTART print arr[2, start], arr[2, length] #二维数组arr[index,length]值RLENGTH } foooo barrrrr 1 5 9 7 复制代码 6想到过用split清空数组么? awk BEGIN{ split(abc,array,) print array[1] array[1],\narray[2] array[2],\narray[3] array[3] split(,array) print array[1] array[1],\narray[2] array[2],\narray[3] array[3] } array[1] a array[2] b array[3] c array[1] array[2] array[3] 复制代码