亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: awk數(shù)組的學(xué)習(xí)心得 [打印本頁]

作者: yinyuemi    時(shí)間: 2011-04-30 08:42
標(biāo)題: awk數(shù)組的學(xué)習(xí)心得
本帖最后由 yinyuemi 于 2011-06-26 00:29 編輯

在文本處理的工作中,awk的數(shù)組是必不可少的工具,在這里,同樣以總結(jié)經(jīng)驗(yàn)和教訓(xùn)的方式和大家分享下我的一些學(xué)習(xí)心得,如有錯(cuò)誤的地方,請(qǐng)大家指正和補(bǔ)充。

awk的數(shù)組,一種關(guān)聯(lián)數(shù)組(Associative Arrays),下標(biāo)可以是數(shù)字和字符串。因無需對(duì)數(shù)組名和元素提前聲明,也無需指定元素個(gè)數(shù) ,所以awk的數(shù)組使用非常靈活。
首先介紹下幾個(gè)awk數(shù)組相關(guān)的知識(shí)點(diǎn):

<1>建立數(shù)組

  1. array[index] = value :數(shù)組名array,下標(biāo)index以及相應(yīng)的值value。
復(fù)制代碼
<2>讀取數(shù)組值

  1. { for (item in array)  print array[item]} # 輸出的順序是隨機(jī)的
  2. {for(i=1;i<=len;i++)  print array[i]} # Len 是數(shù)組的長度
復(fù)制代碼
<3>多維數(shù)組,array[index1,index2,……]:SUBSEP是數(shù)組下標(biāo)分割符,默認(rèn)為“\034”?梢允孪仍O(shè)定SUBSEP,也可以直接在SUBSEP的位置輸入你要用的分隔符,如:

  1. awk 'BEGIN{SUBSEP=":";array["a","b"]=1;for(i in array) print i}'
  2. a:b
  3. awk 'BEGIN{array["a"":""b"]=1;for(i in array) print i}'
  4. a:b
復(fù)制代碼
但,有些特殊情況需要避免,如:

  1. awk 'BEGIN{
  2. SUBSEP=":"
  3. array["a","b:c"]=1               # 下標(biāo)為“a:b:c”
  4. array["a:b","c"]=2               #下標(biāo)同樣是“a:b:c”
  5. for (i in array) print i,array[i]}'
  6. a:b:c 2                                 #所以數(shù)組元素只有一個(gè)。
復(fù)制代碼
<4>刪除數(shù)組或數(shù)組元素: 使用delete 函數(shù)

  1. delete array                     #刪除整個(gè)數(shù)組
  2. delete array[item]           # 刪除某個(gè)數(shù)組元素(item)
復(fù)制代碼
<5> 排序:awk中的asort函數(shù)可以實(shí)現(xiàn)對(duì)數(shù)組的值進(jìn)行排序,不過排序之后的數(shù)組下標(biāo)改為從1到數(shù)組的長度。在gawk 3.1.2以后的版本還提供了一個(gè)asorti函數(shù),這個(gè)函數(shù)不是依據(jù)關(guān)聯(lián)數(shù)組的值,而是依據(jù)關(guān)聯(lián)數(shù)組的下標(biāo)排序,即asorti(array)以后,仍會(huì)用數(shù)字(1到數(shù)組長度)來作為下標(biāo),但是array的數(shù)組值變?yōu)榕判蚝蟮脑瓉淼南聵?biāo),除非你指定另一個(gè)參數(shù)如:asorti(a,b)。(非常感謝lionfun對(duì)asorti的指正和補(bǔ)充


  1. echo 'aa
  2. bb
  3. aa
  4. bb
  5. cc' |\
  6. awk '{a[$0]++}END{l=asorti(a);for(i=1;i<=l;i++)print a[i]}'
  7. aa
  8. bb
  9. cc

  10. echo 'aa
  11. bb
  12. aa
  13. bb
  14. cc' |\
  15. awk '{a[$0]++}END{l=asorti(a,b);for(i=1;i<=l;i++)print b[i],a[b[i]]}'
  16. aa 2
  17. bb 2
  18. cc 1
復(fù)制代碼


下面說awk數(shù)組的實(shí)際應(yīng)用。

1.  除去重復(fù)項(xiàng), 這個(gè)不多說, 只給出代碼:

  1. awk '!a[$0]++' file(s)                  
  2. awk '!($0 in a){a[$0];print}' file(s)   
復(fù)制代碼
另一種:http://www.72891.cn/thread-1859344-1-1.html

2. 計(jì)算總數(shù)(sum),如:

  1. awk  '{name[$0]+=$1};END{for(i in name) print  i, name[i]}'

  2. 再舉個(gè)例子:

  3. echo "aaa 1
  4. aaa 1
  5. ccc 1
  6. aaa 1
  7. bbb 1
  8. ccc 1" |awk '{a[$1]+=$2}END{for(i in a) print i,a[i]}'
  9. aaa 3
  10. bbb 1
  11. ccc 2


復(fù)制代碼
3. 查看文件差異。

  1. cat file1
  2. aaa
  3. bbb
  4. ccc
  5. ddd
  6. cat file2
  7. aaa
  8. eee
  9. ddd
  10. fff
復(fù)制代碼
<1>  合并file1和file2,除去重復(fù)項(xiàng):

  1. awk 'NR==FNR{a[$0]=1;print}   #讀取file1,建立數(shù)組a,下標(biāo)為$0,并賦值為1,然后打印
  2. NR>FNR{                   #讀取file2
  3. if(!(a[$0])) {print }      #如果file2 的$0不存在于數(shù)組a中,即不存在于file1,則打印。
  4. }' file1 file2
  5. aaa
  6. bbb
  7. ccc
  8. ddd
  9. eee
  10. fff
復(fù)制代碼
<2> 提取文件1中有,但文件2中沒有:

  1. awk 'NR==FNR{a[$0]=1}           #讀取file2,建立數(shù)組a,下標(biāo)為$0,并賦值為1
  2. NR>FNR{                   #讀取file1
  3. if(!(a[$0])) {print }      #如果file1 的$0不存在于數(shù)組a中,即不存在于file2,則打印。
  4. }' file2 file1
  5. bbb
  6. ccc
復(fù)制代碼
另:http://www.72891.cn/viewthr ... &page=1#pid15547885

4.  排序:

  1. echo "a
  2. 1
  3. 0
  4. b
  5. 2
  6. 10
  7. 8
  8. 100" |
  9. awk '{a[$0]=$0} #建立數(shù)組a,下標(biāo)為$0,賦值也為$0
  10. END{
  11. len=asort(a)      #利用asort函數(shù)對(duì)數(shù)組a的值排序,同時(shí)獲得數(shù)組長度len
  12. for(i=1;i<=len;i++) print i "\t"a[i]  #打印
  13. }'
  14. 1       0
  15. 2       1
  16. 3       2
  17. 4       8
  18. 5       10
  19. 6       100
  20. 7       a
  21. 8       b
復(fù)制代碼
5.  有序輸出:采用(index in array)的方式打印數(shù)組值的順序是隨機(jī)的,如果要按原序輸出,則可以使用下面的方法:http://bbs2.chinaunix.net/viewthread.php?tid=1811279

  1. awk '{a[$1]=$2
  2. c[j++]=$1}
  3. END{
  4. for(m=0;m<j;m++)print c[m],a[c[m]]
  5. }'
復(fù)制代碼
6.  多個(gè)文本編輯:這里主要指的是待處理的文本之間的格式上有區(qū)別,如分隔符不同,;或是待處理文本需提取的信息的位置不同,如不同的列或行。
<例1>:

  1. cat file1
  2. g1.1 2
  3. g2.2 4
  4. g2.1 5
  5. g4.1 3
  6. cat file2
  7. g1.1 2
  8. g1.2 3
  9. g4.1 4
  10. cat file3
  11. g1.2 3
  12. g5.1 3
復(fù)制代碼
要求輸出:

  1. g1.1 2 2 -
  2. g1.2 - 3 3
  3. g2.2 4 - -
  4. g2.1 5 - -
  5. g4.1 3 4 -
  6. g5.1 - - 3
復(fù)制代碼
實(shí)現(xiàn)代碼如下:

  1. awk '{a[ARGIND" "$1]=$2 # ARGIND是當(dāng)前命令行文件的位置(從0開始),將它和第一列的value作為下標(biāo),建立數(shù)組a。
  2.        b[$1]   #將第一列的value作為下標(biāo),建立數(shù)組b,目的是在讀完所有文件之后,能得到第一列value的uniqe-list。
  3.         }
  4. END{
  5.         for(i in b) {
  6.                 printf i" "
  7.                 for(j=1;j<=ARGIND;j++) printf "%s ", a[j" "i]?a[j" "i]:"-" #此時(shí)的ARGIND值為3.
  8. print ""
  9.                 }
  10.         }' file1 file2 file3
復(fù)制代碼
這里是利用awk的內(nèi)置變量ARGIND來處理完成對(duì)文件的處理。關(guān)于ARGIND,ARGV,ARGC的使用,大家可以參考:http://www.72891.cn/viewthr ... 0335&from=favorites。
當(dāng)然,我們也可以利用另外一個(gè)內(nèi)置變量FILENAME來完成相同的任務(wù)(大家可以先想想怎么寫),如下:

  1. 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
復(fù)制代碼
<例2>:對(duì)上面的數(shù)據(jù)的格式稍作改動(dòng),每個(gè)文件的分隔符都一樣的情況,但輸出要求不變:

  1. cat file1
  2. g1.1|2
  3. g2.2|4
  4. g2.1|5
  5. g4.1|3
  6. cat file2
  7. g1.1#2
  8. g1.2#3
  9. g4.1#4
  10. cat file3
  11. g1.2@3
  12. g5.1@3
復(fù)制代碼
實(shí)現(xiàn)代碼如下:

  1. awk '{a[ARGIND" "$1]=$2
  2. b[$1]
  3. }
  4. END{
  5. for(i in b) {
  6. printf i" "
  7. for(j=2;j<=ARGIND;j+=2) printf "%s ", a[j" "i]?a[j" "i]:"-" # 由于FS的設(shè)置也是有對(duì)應(yīng)ARGIND值,所以對(duì)ARGIND稍作改動(dòng)。
  8. print ""
  9. }
  10. }' FS="|" file1 FS="#" file2 FS="@" file3 # 對(duì)每個(gè)文件分別設(shè)置FS的值。
復(fù)制代碼
因?yàn)檫@個(gè)例子的數(shù)據(jù)比較簡(jiǎn)單,我們也可以在BEGIN模塊中完成對(duì)FS值設(shè)置,如下:

  1. awk 'BEGIN{FS="[|#@]"}{a[ARGIND" "$1]=$2; b[$1]}END{for(i in b) {printf i" ";for(j=1;j<=ARGIND;j++) printf "%s ", a[j" "i]?a[j" "i]:"-"; print ""}}' file1 file2 file3
復(fù)制代碼
利用FILENAME 同樣可以解決問題:

  1. awk '
  2. FILENAME=="file1"{FS="|"}    # 設(shè)置FS
  3. FILENAME=="file2"{FS="#"}   #設(shè)置FS
  4. FILENAME=="file3"{FS="@"}  #設(shè)置FS
  5. # 稍顯繁瑣,不過一目了然
  6. {$0=$0}                                   #使FS生效。
  7. {a[ARGIND" "$1]=$2; b[$1]}
  8. END{ for(i in b) {printf i" "; for(j=1;j<=ARGIND;j++) printf "%s ", a[j" "i]?a[j" "i]:"-"; print ""}
  9. }' file1 file2 file3
復(fù)制代碼
推薦一個(gè)關(guān)于數(shù)組處理文件的帖子http://www.chinaunix.net/jh/24/577044.html ,里面有不少例子供大家學(xué)習(xí)。

7.  文本翻轉(zhuǎn)或移位:二維或多維數(shù)組的應(yīng)用
<例1>:

  1. Inputfile
  2. 1 2 3 4 5 6
  3. 2 3 4 5 6 1
  4. 3 4 5 6 1 2
  5. 4 5 6 1 2 3
  6. Outputfile
  7. 4 3 2 1
  8. 5 4 3 2
  9. 6 5 4 3
  10. 1 6 5 4
  11. 2 1 6 5
  12. 3 2 1 6

  13. awk '{
  14.      if (max_nf < NF)
  15.           max_nf = NF # 數(shù)組第一維的長度
  16.      max_nr = NR      # 數(shù)組第二維的長度
  17.      for (x = 1; x <= NF; x++)
  18.           vector[x, NR] = $x #建立數(shù)組vector
  19. }
  20. END {
  21.      for (x = 1; x <= max_nf; x++) {
  22.           for (y = max_nr; y >= 1; --y)
  23.                printf("%s ", vector[x, y])
  24.           printf("\n")
  25.      }
  26. }'
復(fù)制代碼
<例2>:來自http://www.72891.cn/viewthr ... &page=1#pid13339226
有兩個(gè)文本a和b,要求輸出c文本,合并的規(guī)則是按照第一行的headline(按字母順序)合并文本a和b,空缺按“0”補(bǔ)齊。

  1. cat a.txt
  2. a b c d
  3. 1 2 9 7
  4. 4 5 8 9
  5. 5 3 6 1
  6. cat b.txt
  7. a e f d g
  8. 9 2 4 7 3
  9. 4 3 7 9 4
  10. cat c.txt
  11. a b c d e f g
  12. 1 2 9 7 0 0 0
  13. 4 5 8 9 0 0 0
  14. 5 3 6 1 0 0 0
  15. 9 0 0 7 2 4 3
  16. 4 0 0 9 3 7 4
復(fù)制代碼
下面我們來參看并解讀下Tim大師的代碼:

  1. awk '
  2. FNR==1{    #FNR==1,即a和b文本的第一行,這個(gè)用的真的很巧妙。
  3.         for(i=1;i<=NF;i++){
  4.                 b[i]=$i    #讀取文本的每個(gè)元素存入數(shù)組b
  5.                 c[$i]++}  #另建立數(shù)組c,并統(tǒng)計(jì)每個(gè)元素的個(gè)數(shù)
  6.                 next          #可以理解為,讀取FNR!=1的文本內(nèi)容。
  7.         }
  8. {k++                                     # 統(tǒng)計(jì)除去第一行的文本行數(shù)
  9. for(i=1;i<=NF;i++)a[k","b[i]]=$i  #利用一個(gè)二維數(shù)組來保持每個(gè)數(shù)字的位置, k,b[i]可以理解為每個(gè)數(shù)字的坐標(biāo)。
  10. }
  11. END{
  12.         l=asorti(c)          #利用asorti函數(shù)對(duì)數(shù)組的下標(biāo)進(jìn)行排序,并獲取數(shù)組長度,即輸出文件的列數(shù)(NF值)
  13.         for(i=1;i<=l;i++)printf c[i]" " # 先打印第一行,相當(dāng)于headline。
  14.         print ""
  15.         for(i=1;i<=k;i++){
  16.                 for(j=1;j<=l;j++)printf a[i","c[j]]?a[i","c[j]]" ":"0 " # 打印二維數(shù)組的值。
  17.                 print ""}
  18.         }' a.txt b.txt
復(fù)制代碼
8.  選擇性打。
打印某個(gè)關(guān)鍵字前幾行,以3行為例:

  1. seq 20 |awk '/\<10\>/{for(i=NR-3;i<NR;i++)print a[i%3];exit}{a[NR%3]=$0}'
  2. 7
  3. 8
  4. 9
復(fù)制代碼
利用NR取余數(shù),建立數(shù)組,這是一種非常高效的代碼。

9. 通過split函數(shù)建立數(shù)組:數(shù)組的下標(biāo)為從1開始的數(shù)字。

  1. split(s, a [, r]) # s:string, a:array name,[,r]:regular expression。
  2. echo 'abcd' |awk '{len=split($0,a,"");for(i=1;i<=len;i++) print "a["i"] = " a[i];print "length = " len}'
  3. a[1] = a
  4. a[2] = b
  5. a[3] = c
  6. a[4] = d
  7. length = 4
復(fù)制代碼
10. awk數(shù)組使用的小技巧和需要避免的用法:

<1> 嵌套數(shù)組:

  1. awk 'BEGIN{a[1]=3;b[1]=1;print a[b[1]]}'
  2. 3
復(fù)制代碼
<2> 下標(biāo)設(shè)為變量或函數(shù):

  1. awk 'BEGIN{s=123;a[substr(s,2)]=substr(s,1,1);for(i in a)print "index : "i"\nvalue : "a[i]}'
  2. index : 23
  3. value : 1
復(fù)制代碼
<3> 不可以將數(shù)組名作為變量使用,否則會(huì)報(bào)錯(cuò):

  1. awk 'BEGIN{a["1"] = 3; delete a;a=3;print a}'  #即使你已經(jīng)使用了delete函數(shù)。
  2. awk: fatal: attempt to use array `a' in a scalar context
復(fù)制代碼
<4> 數(shù)組的長度:

  1. length(array)  
復(fù)制代碼
<5> match 函數(shù)也可以建立數(shù)組(你知道么?,版本要求高于gawk 3.1.2)

  1. echo "foooobazbarrrrr |
  2. gawk '{ match($0, /(fo+).+(bar*)/, arr)  #匹配到的部分自動(dòng)賦值到arr中,下標(biāo)從1開始
  3.           print arr[1], arr[2]
  4.           print arr[1, "start"], arr[1, "length"]  #二維數(shù)組arr[index,"start"]值=RSTART
  5.           print arr[2, "start"], arr[2, "length"]  #二維數(shù)組arr[index,"length"]值=RLENGTH
  6.           }'
  7. foooo barrrrr
  8. 1 5
  9. 9 7
復(fù)制代碼
<6>想到過用split清空數(shù)組么?

  1. awk 'BEGIN{
  2. split("abc",array,"")
  3. print "array[1] = "array[1],"\narray[2] = "array[2],"\narray[3] = "array[3]
  4. split("",array)
  5. print "array[1] = "array[1],"\narray[2] ="array[2],"\narray[3] ="array[3]
  6. }'
  7. array[1] = a
  8. array[2] = b
  9. array[3] = c
  10. array[1] =
  11. array[2] =
  12. array[3] =
復(fù)制代碼

作者: Shell_HAT    時(shí)間: 2011-04-30 10:16
感謝樓主的無私奉獻(xiàn)
作者: yinyuemi    時(shí)間: 2011-04-30 10:28
回復(fù) 2# Shell_HAT


    說感謝的應(yīng)該是我,我在CU學(xué)到很多東西,非常感謝各位老大們的支持和幫助啊
作者: ziyunfei    時(shí)間: 2011-04-30 10:44

作者: fangtong2008    時(shí)間: 2011-04-30 11:06
好文 學(xué)習(xí)了!
作者: fangtong2008    時(shí)間: 2011-04-30 15:13
2. 計(jì)算總數(shù)(sum),如:

    awk  '{name[$0]+=$1};END{for(i in name) print  i, name[i]}'
這個(gè)也是去重吧?
作者: expert1    時(shí)間: 2011-04-30 20:59
回復(fù) 3# yinyuemi


    居然有個(gè)鏈接是我之前寫的,呵呵,考古挖墳了一下
作者: xrzs1986    時(shí)間: 2011-05-01 01:18

作者: yinyuemi    時(shí)間: 2011-05-02 01:45
回復(fù) 6# fangtong2008


    恩,可以,因?yàn)閿?shù)組下標(biāo)是沒有重復(fù)的
作者: ontherd    時(shí)間: 2011-05-02 12:39
好帖必須頂起來~
其實(shí),來到這里,給我的收獲是非常,非常,非! …… ……大
作者: 小小linux    時(shí)間: 2011-05-03 09:39
好東西。。

作者: bjyuxiao    時(shí)間: 2011-05-03 14:25
好帖子。感謝分享
作者: 南極雨    時(shí)間: 2011-05-03 15:50
回復(fù) 1# yinyuemi

如果把a(bǔ)wk函數(shù)也貼出來,哇塞,完美了...
作者: 南極雨    時(shí)間: 2011-05-03 20:04
回復(fù) 1# yinyuemi


請(qǐng)教一個(gè)問題:
  1. 計(jì)算總數(shù)(sum),如:
  2. awk  '{name[$0]+=$1};END{for(i in name) print  i, name[i]}'
復(fù)制代碼
name[$0]+=$1
+ 是什么意思啊? 這個(gè)有什么意義嗎?
作者: 網(wǎng)中淫    時(shí)間: 2011-05-03 21:47
  1. name[$0]=name[$0]+$1
復(fù)制代碼
簡(jiǎn)寫,沒什么特殊的意義
作者: Shell_HAT    時(shí)間: 2011-05-03 21:53
回復(fù) 13# 南極雨


哪個(gè)awk函數(shù)?
作者: yinyuemi    時(shí)間: 2011-05-03 23:08
本帖最后由 yinyuemi 于 2011-05-04 07:21 編輯

回復(fù) 13# 南極雨


   
awk的函數(shù)使用可以查看awk教程或google下,多練習(xí)使用。
http://www.math.utah.edu/docs/info/gawk_13.html

“a+=1” 相當(dāng)于“a=a+1”
作者: 南極雨    時(shí)間: 2011-05-04 09:25
回復(fù) 16# Shell_HAT

自定義的,比如時(shí)間計(jì)算之類的,還有函數(shù)調(diào)用
作者: 南極雨    時(shí)間: 2011-05-04 09:29
本帖最后由 南極雨 于 2011-05-04 09:32 編輯

回復(fù) 17# yinyuemi

+ 號(hào)的實(shí)際用法,我了解一點(diǎn),看了你的" awk數(shù)組的實(shí)際應(yīng)用" 中的第二個(gè)例子,有點(diǎn)不太理解,這個(gè)+ 號(hào)有什么意義嗎?因?yàn)槲覝y(cè)試了一下,沒有+也可以正確輸出.
或者在其他的例子里面是不是有什么其他的用途呢?





這么說吧 ,awk 每次處理一行,a[$0]+=$1 也只對(duì)當(dāng)前輸入行有意義,也就是a[$0]=$1,而對(duì)下一行沒有意義,下一行則是完全獨(dú)立的a[$0]=$1 ,這樣說對(duì)嗎?
作者: Shell_HAT    時(shí)間: 2011-05-04 10:01
回復(fù) 18# 南極雨


能給個(gè)自定義的例子看看么?
作者: Shell_HAT    時(shí)間: 2011-05-04 10:04
回復(fù) 19# 南極雨


第二個(gè)例子是計(jì)算總數(shù)(sum)
你把+=改成=,還能實(shí)現(xiàn)這個(gè)功能么?
作者: 南極雨    時(shí)間: 2011-05-04 11:01
回復(fù) 21# Shell_HAT

為什么name[42]的值會(huì)是42呢?

在文件中:
# [root@localhost awk]# cat file
# 1214 42  5 34  543 54
# 2323 434 43 34 434 44
# 122  32
# 1213 324 4345 456 56 77
# 1233 q3 we23 <F2>2342 2342
# 213 213 546 798 987 654
#
END 語句中i的值會(huì)遍歷所有數(shù)組下表,當(dāng)i=42時(shí),name[42]=42
[root@danoolive ~]# awk  '{name[$2]=$2;print  name["42"]}' file
42
42
42
42
42
42

我寫的有點(diǎn)太絕對(duì)了,沒有說前提條件,誤會(huì)誤會(huì)了...不好意思!

+=計(jì)算總數(shù)(sum)
這個(gè)是不是應(yīng)該放在END 里面呢?
作者: 南極雨    時(shí)間: 2011-05-04 11:02
回復(fù) 21# Shell_HAT


   
為什么name[42]的值會(huì)是42呢?

在文件中:
# [root@localhost awk]# cat file
# 1214 42  5 34  543 54
# 2323 434 43 34 434 44
# 122  32
# 1213 324 4345 456 56 77
# 1233 q3 we23 <F2>2342 2342
# 213 213 546 798 987 654
#
END 語句中i的值會(huì)遍歷所有數(shù)組下表,當(dāng)i=42時(shí),name[42]=42
[root@danoolive ~]# awk  '{name[$2]=$2;print  name["42"]}' file
42
42
42
42
42
42

我寫的有點(diǎn)太絕對(duì)了,沒有說前提條件,誤會(huì)誤會(huì)了...不好意思!

+=計(jì)算總數(shù)(sum)
這個(gè)是不是應(yīng)該放在END 里面呢?
作者: yinyuemi    時(shí)間: 2011-05-04 11:46
回復(fù) 19# 南極雨


    不好意思,應(yīng)該是我舉的例子不好,如果整個(gè)文本的沒有重復(fù)的話,就是你說的a[$0]+=$1 和a[$0]=$1是一樣的,如果有重復(fù)的話就不一樣了,舉個(gè)例子吧,

  1. echo "1 a
  2. 1 b
  3. 2 a
  4. 2 b" |awk '{print "a[$0]+ = ",a[$0]+=$1, "a[$0] = ", a[$0]=$1}'
  5. a[$0]+ =  1 a[$0] =  1
  6. a[$0]+ =  1 a[$0] =  1
  7. a[$0]+ =  2 a[$0] =  2
  8. a[$0]+ =  2 a[$0] =  2

  9. echo "1 a
  10. 1 a
  11. 2 a
  12. 2 a" |awk '{print "a[$0]+ = ",a[$0]+=$1, "a[$0] = ", a[$0]=$1}'
  13. a[$0]+ =  1 a[$0] =  1
  14. a[$0]+ =  2 a[$0] =  1
  15. a[$0]+ =  2 a[$0] =  2
  16. a[$0]+ =  4 a[$0] =  2

復(fù)制代碼

作者: 南極雨    時(shí)間: 2011-05-04 13:08
回復(fù) 24# yinyuemi


是我不好意思,我又鉆牛角尖里面了,這么簡(jiǎn)單的問題,稍微多想一點(diǎn)兒就知道了...
作者: 392575160    時(shí)間: 2011-05-04 19:08
提示: 該帖被管理員或版主屏蔽
作者: howge    時(shí)間: 2011-05-05 10:19
好貼,頂!
作者: yinyuemi    時(shí)間: 2011-06-26 00:34
第七題的例二中的:l=asorti(c) 你的解釋是沒有問題的,但是好像漏寫點(diǎn)
你解釋說:利用asorti函數(shù)對(duì)數(shù)組的下標(biāo)進(jìn)行排序,并獲取數(shù)組長度,即輸出文件的列數(shù)(NF值)
好像你沒有把a(bǔ)sorti的功能的另一個(gè)特點(diǎn)說出來,它與asort是不一樣。asorti(a)了以后會(huì)用數(shù)字來作為indices,但是它會(huì)用原來的indices作為數(shù)組的值,除非你指定另一個(gè)參數(shù)如:asorti(a,b)。

感謝lionfun兄弟對(duì)asorti函數(shù)部分的指正和補(bǔ)充
作者: 267020090    時(shí)間: 2011-06-26 21:15
最近正在研究數(shù)組 先頂在看
作者: fengfeng919    時(shí)間: 2011-07-29 10:38
yinyuemi,你好:

請(qǐng)問awk里面一種求平均值的使用方式,a[$1]+=$2  看不懂,解釋一下唄,謝~
作者: yinyuemi    時(shí)間: 2011-07-29 12:35
回復(fù) 30# fengfeng919

  1.     echo 'a 1
  2. b 1
  3. a 2
  4. b 2
  5. a 3
  6. b 3' |\
  7. awk '{a[$1]+=$2;b[$1]++}END{for(i in a)print i,a[i]/b[i]}' #數(shù)組a求和,b數(shù)組求次數(shù),最后打印平均值
  8. a 2
  9. b 2
復(fù)制代碼

作者: fengfeng919    時(shí)間: 2011-07-29 14:21
本帖最后由 fengfeng919 于 2011-07-29 14:23 編輯
回復(fù)  fengfeng919
yinyuemi 發(fā)表于 2011-07-29 12:35



    整體意思我了解,就是 a[$1]+=$2 形式,它咋就成了求和的意義了呢,這種用法我不理解,沒有C基礎(chǔ),杯具我,也不知道是不是鉆了牛角尖 -_-
作者: yinyuemi    時(shí)間: 2011-07-29 14:23
回復(fù) 32# fengfeng919


    21樓正好是說這個(gè)的
作者: qpengf    時(shí)間: 2011-08-01 15:30
好貼啊
作者: java_html    時(shí)間: 2011-08-02 16:12
回復(fù) 1# yinyuemi


<4> 數(shù)組的長度:
length(array)  

這個(gè)好像不能算出數(shù)組的長度???例如:
echo 'a
b' | awk '{array[$1]++} END{ print length(array)}'
報(bào)錯(cuò):
無法讀取值 a。它是一個(gè)數(shù)組名
注:
length函數(shù)是計(jì)算字符串的字符個(gè)數(shù)。
作者: yinyuemi    時(shí)間: 2011-08-02 23:13
回復(fù) 35# java_html
  1. echo 'a
  2. b' | awk '{array[$1]++} END{ print length(array)}'
  3. 2
復(fù)制代碼
沒問題啊, 你測(cè)試的代碼是這個(gè)么?
作者: java_html    時(shí)間: 2011-08-03 10:28
回復(fù) 36# yinyuemi


    awk版本有點(diǎn)低,不支持;awk 3.1.6支持。×硪粏栴},在aix的ksh下查看awk版本真心難,,man awk沒有版本信息。
作者: yinyuemi    時(shí)間: 2011-08-03 12:06
回復(fù) 37# java_html


    試試awk --version
作者: Young_Xu666    時(shí)間: 2011-08-03 19:59
學(xué)習(xí)了。謝謝!
作者: d_jacky    時(shí)間: 2011-08-04 09:13
本帖最后由 d_jacky 于 2011-08-04 09:17 編輯

問一下,這條指令為什么要這樣寫,謝謝
oracle@node2:~> seq 20 |awk '/\<10\>/{for(i=NR-3;i<NR;i++)print a[i%3];exit}{a[NR%3]=$0;}'             而這里卻只打印前三行,謝謝。改如何解釋
7
8
9
oracle@node2:~> seq 20 |awk '/\<10\>/{for(i=NR-3;i<NR;i++)print a[i%3];exit}{print a[NR%3]=$0;}'       為什么多了一個(gè)print就把所有的打印了
1
2
3
4
5
6
7
8
9
7
8
9
作者: yinyuemi    時(shí)間: 2011-08-04 09:19
回復(fù) 40# d_jacky


    你的問題就是答案
   第一個(gè)代碼中{a[NR%3]=$0;}用來給數(shù)組賦值,
   第二個(gè)代碼中{print a[NR%3]=$0;},除了賦值,還要打印
作者: 南極雨    時(shí)間: 2011-08-17 10:57
本帖最后由 南極雨 于 2011-08-17 11:03 編輯

回復(fù) 1# yinyuemi


看了十幾遍啊................................,終于看到一點(diǎn)可以補(bǔ)充的了, 呵呵:
awk 實(shí)際應(yīng)用:
3-1
查看文件差異:

cat file1
aaa
bbb
ccc
ddd
cat file2
aaa
eee
ddd
fff

合并file1 file2 去除重復(fù)項(xiàng):

如果file1內(nèi)有重復(fù)項(xiàng), 這個(gè)就不能合并了,例如:

cat file1
aaa
bbb
ccc
ddd
ddd


cat file2
aaa
eee
ddd
fff
  1. awk 'NR==FNR{a[$0]=1;print}NR>FNR{if(!(a[$0])) {print}}' file1 file2
  2. aaa
  3. bbb
  4. ccc
  5. ddd
  6. ddd
  7. eee
  8. fff
復(fù)制代碼
改成:
  1. [root@localhost ~]# awk 'NR==FNR{if(!a[$0]++) print}NR>FNR{if(!(a[$0])) {print}}' a b
  2. aaa
  3. bbb
  4. ccc
  5. ddd
  6. eee
  7. fff
復(fù)制代碼
file2 文件也一樣....
[root@localhost ~]# cat file2
aaa
eee
ddd
fff
fff
  1. [root@localhost ~]# awk 'NR==FNR{if(!a[$0]++) print}NR>FNR{if(!(a[$0])) {print}}' file1 file2
  2. aaa
  3. bbb
  4. ccc
  5. ddd
  6. eee
  7. fff
  8. fff
復(fù)制代碼
  1. [root@localhost ~]# awk 'NR==FNR{if(!a[$0]++) print}NR>FNR{if(!(a[$0]++)) {print}}' file1 file2
  2. aaa
  3. bbb
  4. ccc
  5. ddd
  6. eee
  7. fff
復(fù)制代碼
綜合起來就可以寫成:
awk '!a[$0]++' file1 file2 了....
作者: yinyuemi    時(shí)間: 2011-08-17 11:52
回復(fù) 42# 南極雨


    多謝補(bǔ)充!看來具體情況具體分析是非常必要的,呵呵
作者: six_alibaba    時(shí)間: 2011-09-21 13:43
不錯(cuò)。學(xué)習(xí)了
作者: crulat    時(shí)間: 2011-09-22 11:32
好帖,頂了!
作者: tt_yy123    時(shí)間: 2011-11-14 16:57
回復(fù) 1# yinyuemi


      合并file1和file2,除去重復(fù)項(xiàng):
awk 'NR==FNR{a[$0]=1;print}   #讀取file1,建立數(shù)組a,下標(biāo)為$0,并賦值為1,然后打印

NR>FNR{                   #讀取file2

if(!(a[$0])) {print }      #如果file2 的$0不存在于數(shù)組a中,即不存在于file1,則打印。

}' file1 file2

aaa

bbb

ccc

ddd

eee

fff

a[$0]=1====>為什么要等于1啊,必須這樣寫么?
作者: airstorm    時(shí)間: 2011-11-14 18:00
真的很好,看了這個(gè)后感覺好多以前無解的都豁然開朗了,謝謝樓主分享。
作者: 7717060    時(shí)間: 2011-11-15 00:06
收藏
作者: yinyuemi    時(shí)間: 2011-11-15 01:20
回復(fù)  yinyuemi


      合并file1和file2,除去重復(fù)項(xiàng):
awk 'NR==FNR{a[$0]=1;print}   #讀取file1 ...
tt_yy123 發(fā)表于 2011-11-14 16:57



   
a[$0]=1====>為什么要等于1啊,必須這樣寫么?

    不是必須的,你可以給他賦予任何值,甚至是0.(如果是0的話,你考慮下if語句怎么寫?)
    另外,也可以不給數(shù)組a賦值,直接使用a[$0], 這樣的話,if語句可以使用!($0 in a).
作者: fhefh    時(shí)間: 2011-11-21 23:12
太經(jīng)典 太強(qiáng)大 無意間看到帖子

收藏之
作者: vnb2018    時(shí)間: 2011-11-22 08:33
大俠,想請(qǐng)教個(gè)問題:
awk '{a[$1]++} END{for(i in a) print i ,a[i]}' file
問題1:a[$1]++ 這是什么意思阿?難道是a[$1]初值是0,然后加加,統(tǒng)計(jì)個(gè)數(shù)?
問題2:for(i in a) print i a[i] 這個(gè)語句,輸出是隨機(jī)輸出,但是我測(cè)試了兩組數(shù)據(jù),都是將file中最后兩組數(shù)據(jù)給顛倒了
作者: wenxin588    時(shí)間: 2012-01-31 09:01
恩,找了好久,終于找到類似的了~~
作者: lastfile    時(shí)間: 2012-02-06 01:09
好東西,收藏
作者: 洋芋壹代    時(shí)間: 2012-02-07 10:00
不錯(cuò),太有收藏價(jià)值了
作者: ulovko    時(shí)間: 2012-04-22 14:24
一直找AWK 的資料 終于在CU找到了
作者: Shell_HAT    時(shí)間: 2012-04-22 15:01
回復(fù) 55# ulovko


O'Reilly sed & awk 2nd Edition 英文版
http://www.72891.cn/viewthread.php?tid=1588614#pid11286082

O'Reilly sed & awk 2nd Edition 中文高清修訂第3版
http://www.72891.cn/thread-1743038-1-1.html

sed and awk 101 hacks
http://www.72891.cn/thread-3629499-1-1.html

awk1line & sed1line 注解補(bǔ)充版&cheat sheets
http://www.72891.cn/thread-1635180-1-1.html

awk1line實(shí)現(xiàn)sed1line
http://www.72891.cn/thread-2318664-1-1.html

三篇awk學(xué)習(xí)資料
http://www.72891.cn/thread-1425973-1-4.html
作者: Shell_HAT    時(shí)間: 2012-04-22 15:03
回復(fù) 51# vnb2018


http://www.72891.cn/viewthread.php?tid=1672726#pid11904888
作者: ulovko    時(shí)間: 2012-04-22 15:06
回復(fù) 56# Shell_HAT


    多謝了,正在看!
作者: 我是羅納爾多    時(shí)間: 2012-04-27 19:19
我也來頂一下..
作者: kk5234    時(shí)間: 2012-04-29 16:55
回復(fù) 56# Shell_HAT


    太給力了!謝謝!
作者: Killercn    時(shí)間: 2012-05-07 18:13
好帖必須頂起來~
作者: shaneqi    時(shí)間: 2012-05-24 17:12
回復(fù)一下吧
作者: Linux9253    時(shí)間: 2012-06-01 15:57
收獲相當(dāng)?shù)拇?img src="static/image/smiley/default/em03.gif" smilieid="147" border="0" alt="" />
作者: 天下飛松    時(shí)間: 2012-06-05 16:58
多謝樓主回復(fù) 1# yinyuemi


   
作者: ulovko    時(shí)間: 2012-07-10 07:22
總結(jié)的真詳細(xì) 贊! ^_^
作者: hansion3406    時(shí)間: 2012-08-24 11:38
沙發(fā),板凳都沒偶的份了。
作者: webmultiple    時(shí)間: 2012-08-27 22:49
非常棒啊,我輩佩服了,就是tim大師那個(gè)腳本中,next行你的注釋感覺理解不了,next如果理解為不執(zhí)行next后面的命令跳過文件當(dāng)前行的處理開始處理下一行,就能理解了,您覺得呢?
作者: yinyuemi    時(shí)間: 2012-08-27 23:00
回復(fù) 67# webmultiple


    這樣理解也可以,F(xiàn)NR==1{CMD1;next}{CMD2}  <==>  FNR==1{CMD1}FNR>1{CMD2}
作者: sophia3333    時(shí)間: 2012-09-07 13:39
a[$1]是什么意思???是第一列數(shù)據(jù)的值么???
作者: sky_551    時(shí)間: 2012-09-25 16:25
03.再舉個(gè)例子:

04.

05.echo "aaa 1

06.aaa 1

07.ccc 1

08.aaa 1

09.bbb 1

10.ccc 1" |awk '{a[$1]+=$2}END{for(i in a) print i,a[i]}'

11.aaa 3

12.bbb 1

13.ccc 2
這里能不能幫我解釋下awk的處理流程是怎樣的,a[$1]+=$2這里我不清楚系統(tǒng)怎樣處理的,謝謝!
作者: tulip0425    時(shí)間: 2012-10-04 19:33
要頂?shù)陌,樓主辛苦了,謝謝
作者: yezj2004    時(shí)間: 2012-12-14 10:24
加油。。。!頂哦!!!!!
作者: cuteorange    時(shí)間: 2012-12-14 18:58
回復(fù) 1# yinyuemi


    UP
作者: meiyuhan    時(shí)間: 2012-12-31 10:00
我繼續(xù)頂你!太好的帖子了 支持
作者: tyw09    時(shí)間: 2012-12-31 11:41
先回復(fù),再細(xì)看,謝謝分享。
作者: Shell_HAT    時(shí)間: 2012-12-31 13:37
最近也看到了數(shù)組其中有幾點(diǎn)書中講的不是很清楚,列入a=$1 在awk中數(shù)組的下表應(yīng)該不能這么寫把?這樣寫把他識(shí)別為一個(gè)字符,那么我文件里面全是數(shù)字。后面的值是這個(gè)值是下表去匹配的值么?比如a[$0]=$1 這個(gè)意思是 在整個(gè)文本中。只遍歷$1這一列么?

看不懂你的問題。給點(diǎn)數(shù)據(jù)說明一下吧
@力哥丶
作者: Shell_HAT    時(shí)間: 2012-12-31 16:16
好吧。我還沒說清楚,是這樣
文件:
a  b   c   d
e  v   n  m
數(shù)組 a 他的下標(biāo)是3的時(shí)候,值為c
a=$4  他的標(biāo)的值是1 值為d、下標(biāo)為2 值為m?

可能你還是沒有理解hash數(shù)組。它和普通的數(shù)組不同,下標(biāo)(或者說key)不光可以是數(shù)字(1、2、3、4),還可以是字符串(a、b、c、d)。
awk里面經(jīng)?吹絘[$4]++之類的用法,作用是統(tǒng)計(jì)第四列每一個(gè)字符串出現(xiàn)的次數(shù)。執(zhí)行過程類似于:
awk讀到第一行的時(shí)候,$4=d,實(shí)際執(zhí)行的是:a[d]++
awk讀到第二行的時(shí)候,$4=m,實(shí)際執(zhí)行的是:a[m]++
@力哥丶
作者: Shell_HAT    時(shí)間: 2012-12-31 18:16
奧。也就是說
a=$4
其實(shí)就是
a[d]=$4
第二行是
a=$4
就是
a[m]=$4
。那么前面的還是存放在數(shù)組上,只不過統(tǒng)計(jì)第四列。

第一行:
a[$1]=a[a]
a[$2]=a
a[$3]=a[c]
a[$4]=a[d]

第二行:
a[$1]=a[e]
a[$2]=a[v]
a[$3]=a[n]
a[$4]=a[m]

@力哥丶
作者: Shell_HAT    時(shí)間: 2013-01-04 16:04
我又來了,
文本:
A 1 2 3 4
B 1 2 3
C 1 2 3 4
awk '{for(i=2;i<=NF;i++)print $1,$i}
這里最后打印的$i 因?yàn)閕=2,直接打印i的時(shí)候i是從2開始的。$i從1開始?但不明白原理。求指點(diǎn)。

你這個(gè)代碼里面什么地方是直接打印i?
@力哥丶
作者: tank064    時(shí)間: 2013-01-04 16:22
:wink:果斷轉(zhuǎn)成PDF收藏
作者: Shell_HAT    時(shí)間: 2013-01-04 16:29
沒有打印“i”就是如果我打印了i 最后他們的順序是從2開始。 如果是 $i就從一開始。所以不明白 最后打印$1是和意思。

i從2開始是因?yàn)槟阍趂or循環(huán)里面定義的i初始值是2
作者: ybb896    時(shí)間: 2013-01-05 11:37
好貼,收藏!
作者: Shell_HAT    時(shí)間: 2013-01-05 14:32
還有一個(gè)問題,就是自己理解的例子,a[$1,++b[$1]]
理解:
1:a是數(shù)組的名字,第一個(gè)$1先記錄文件第一列的內(nèi)容。
2:++b[$1]在第一列重復(fù)出現(xiàn)的每次+1,至少有一次。
3:第一個(gè)$1,不影響++b[$1],完全是倆從概念
4:最后它們的都是a數(shù)組的下表。
最后不明白的就是這樣的寫法他都能起到什么作用呢。

作用是模擬二維數(shù)組
@力哥丶
作者: love0milk    時(shí)間: 2013-01-08 22:09
非常強(qiáng)大!:wink:
作者: xfortune    時(shí)間: 2013-01-09 10:57
mark

作者: hansion3406    時(shí)間: 2013-01-22 09:46
共同發(fā)展!學(xué)習(xí)才會(huì)進(jìn)步,謝了
作者: yezj2004    時(shí)間: 2013-03-23 09:02
謝謝啦,辛苦啦。感謝感謝!
作者: joepayne    時(shí)間: 2013-04-01 11:35
{:3_182:}樓主很強(qiáng)大,初次接觸AWK數(shù)組,受教了!!
作者: _rayzhang    時(shí)間: 2013-05-22 11:00
感謝分享,拜讀了:wink:
作者: Ienovo_qq    時(shí)間: 2013-08-16 17:44
非常感謝樓主的無私奉獻(xiàn),長知識(shí)了。
作者: cmessi    時(shí)間: 2013-09-10 15:54
學(xué)習(xí)了,支持
1!
作者: bingling512    時(shí)間: 2013-09-13 09:01
好文,學(xué)習(xí)了。
作者: yangi1314    時(shí)間: 2013-11-11 16:55
收藏,學(xué)習(xí)
作者: lb2432    時(shí)間: 2013-11-17 22:32
長見識(shí)了,沒有想到awk這么強(qiáng)大。
作者: xuleixuliyun    時(shí)間: 2014-04-09 14:35
在這里學(xué)到了,很多工作中需要的東西lol
作者: 網(wǎng)速20M    時(shí)間: 2014-10-14 20:23
回復(fù)
我發(fā)現(xiàn)好東西我都趕不上熱呼的
作者: 網(wǎng)速20M    時(shí)間: 2014-10-15 10:29
好厲害呀,是在實(shí)踐中學(xué)到的?


作者: stupid_lee    時(shí)間: 2015-01-05 13:47
新人學(xué)習(xí)了,自從來到CUshell板塊,我一直視樓主為大神的
作者: 旋轉(zhuǎn)小馬    時(shí)間: 2015-01-07 17:19
跟隨SS大神的腳步學(xué)習(xí)。!
作者: jokimina    時(shí)間: 2015-01-07 17:22
特意前來學(xué)習(xí) .然后膜拜下。




歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2