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

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 136294 | 回復(fù): 101
打印 上一主題 下一主題

[學習共享] awk初學之常見問題 [復(fù)制鏈接]

論壇徽章:
2
射手座
日期:2014-10-10 15:59:4715-16賽季CBA聯(lián)賽之上海
日期:2016-03-03 10:27:14
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2011-04-26 07:32 |只看該作者 |倒序瀏覽
本帖最后由 yinyuemi 于 2016-12-08 16:14 編輯

從初學awk到現(xiàn)在小有所成,非常感謝CUers的幫助,總結(jié)了下自己曾經(jīng)遇到的問題和犯的錯誤,供初學者借鑒,因本人非計算機專業(yè),對專業(yè)詞匯可能有表述不對的地方,還請指正和補充!


1. awk ‘{code}1’ 中的“1”是干什么的?

一個完整的awk語句為:Awk ‘[patten]{action}……’, 其中pattern缺省為1,action缺省為{print}。

那么awk ‘1’完整的寫法就是awk ‘1{print}’; 同理,awk ‘{print}’完整的寫法也是awk ‘1{print}’。


2. NR和FNR的區(qū)別是啥?

NR: 當前行記錄數(shù)。

FNR: 當前文件的行記錄數(shù)。

當awk處理的文件數(shù)超過1時,NR和FNR才會有區(qū)別。例如:



  1. cat file
  2. a
  3. b
  4. c
  5. d
  6. e
  7. f

  8. awk '{print "NR = " NR "  FNR = " FNR, $0}' file
  9. NR = 1  FNR = 1 a
  10. NR = 2  FNR = 2 b
  11. NR = 3  FNR = 3 c
  12. NR = 4  FNR = 4 d
  13. NR = 5  FNR = 5 e
  14. NR = 6  FNR = 6 f

  15. awk '{print "NR = " NR "  FNR = " FNR, $0}' file file
  16. NR = 1  FNR = 1 a
  17. NR = 2  FNR = 2 b
  18. NR = 3  FNR = 3 c
  19. NR = 4  FNR = 4 d
  20. NR = 5  FNR = 5 e
  21. NR = 6  FNR = 6 f
  22. NR = 7  FNR = 1 a
  23. NR = 8  FNR = 2 b
  24. NR = 9  FNR = 3 c
  25. NR = 10  FNR = 4 d
  26. NR = 11  FNR = 5 e
  27. NR = 12  FNR = 6 f
復(fù)制代碼


3. Awk怎么引入變量?

有兩種方法:

<1>: awk -v var=$VAR '{code}'
<2>: awk '{CODE}'$VAR'{CODE}'
例如:


  1. VAR=XXX

  2. awk -v var=$VAR 'BEGIN{print var}'
  3. XXX

  4. awk 'BEGIN{print "'$VAR'"}'
  5. XXX
復(fù)制代碼

我推薦使用第一種方法,這樣可以避免一些不必要的煩惱。如http://www.72891.cn/thread-1835620-1-1.html


4. 為什么OFS不起作用?

先看一個例子:



  1. echo 'aaa bbb ccc ddd
  2. aaa bbb ccc ddd
  3. aaa bbb ccc ddd
  4. aaa bbb ccc ddd' |awk -v OFS="|" '{print $0}'
  5. aaa bbb ccc ddd
  6. aaa bbb ccc ddd
  7. aaa bbb ccc ddd
  8. aaa bbb ccc ddd
復(fù)制代碼

上面的例子中OFS為什么沒有生效呢,原因是OFS指的是輸出字段分隔符,所以必須對字段進行操作時OFS才會起作用,正確的方法應(yīng)該是:



  1. echo 'aaa bbb ccc ddd
  2. aaa bbb ccc ddd
  3. aaa bbb ccc ddd
  4. aaa bbb ccc ddd' |awk -v OFS="|" '{$1=$1;print $0}'
  5. aaa|bbb|ccc|ddd
  6. aaa|bbb|ccc|ddd
  7. aaa|bbb|ccc|ddd
  8. aaa|bbb|ccc|ddd
復(fù)制代碼

正如Tim大師所講的,$1=$1這個action,是我們對awk撒的謊,目的就是為了使得OFS生效,除此之外,NF+=0也是常用的方法。參考:http://www.72891.cn/viewthread.php?tid=1354674&extra=&page=1



5. 同樣的代碼,別人運行成功,為什么我運行失?

這個問題的原因很多,我這里列舉兩個最常見的,大家可以補充。

<1>: awk版本引起的,如gawk中的一些擴展函數(shù)或變量,在nawk中沒有,或是不同版本的(g/n)awk也會有差別,這樣情況需要重新編寫。

<2>: 文本格式的問題,cat-A file查看一下,如果是,dos2unix應(yīng)該可以解決。

注:書寫錯誤也有可能哦


6. Awk 語句中可以使用{n,m}這樣的正則么?

可以,使用方法:gawk -- re-interval ,其它版本使用方法會有所不同,請大家補充


7. BEGIN 和END 到底是怎么一回事?

有時,對于新手可能也會是個問題。簡單說下:

BEGIN {action} : 讀取文本之前進行的操作。要避免類似下面的寫法:



  1. awk 'BEGIN{ filename =  FILENAME}' file
  2. # or:
  3. awk 'BEGIN{FS=":"; for(i=2;i<=NF;i++) print $i}' file
復(fù)制代碼


如果BEGIN 模塊中使用getline函數(shù)時,情況會有所不同:

  1. cat file
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5

  7. awk 'BEGIN{while (getline <"file") print}' file
  8. 1
  9. 2
  10. 3
  11. 4
  12. 5

復(fù)制代碼

END {action}:
它在整個輸入文件處理完成后被執(zhí)行,同樣無法對文本進行任何操作,如匹配某個pattern執(zhí)行action。


8. print,printf 和sprintf?

print:為一般的打印

printf:可以定義打印格式

sprintf:可以完成和printf相同的功能,不同的是sprintf只能輸出值,并不能完成打印的功能。

12樓-expert1補充::) print默認有個換行\(zhòng)n,
而printf沒有,當然它和C語言的printf類似(awk本是c的近親),能打印各種格式,但默認沒有換行。

例如:



  1. awk 'BEGIN{var=123; print "var = " var}'
  2. var = 123

  3. awk 'BEGIN{var=123;printf "%s %5f\n", "var =",var}'
  4. var = 123.000000

  5. awk 'BEGIN{var=123;sprintf ("%s  %5f\n", "var =",var)}'


  6. awk ‘BEGIN{var1=123;var2=sprintf ("%5f",var1); print "var2 =" var2}’
  7. var2 = 123.000000
復(fù)制代碼


9. “a==b?c:d” ?

這個是一個if語句的簡寫,即conditional expression1 ? expression2: expression3;完整寫法為:

if(a==b) {c} else a9ur7n9vt


10. awk ‘! a[$0]++’ 怎么理解?

這是一個非常經(jīng)典的去重復(fù)項的awk語句,雖然短小,不過涉及到了不少知識點,下面一一解讀:

<1> :”!” 即非。

<2>:a[$0],以$0為數(shù)據(jù)下標,建立數(shù)組a

<3>:a[$0]++,即給數(shù)組a賦值,a[$0]+=1

<4> :那么組合起來,awk是怎么執(zhí)行!a[$0]++的呢?我用一個實際例子來解釋:



  1. cat file
  2. 111
  3. 222
  4. 111
  5. 222
  6. 333

  7. awk '{print a[$0],!a[$0]++,a[$0],!a[$0],$0}' file
  8.   1 1 0 111
  9.   1 1 0 222
  10. 1 0 2 0 111
  11. 1 0 2 0 222
  12.   1 1 0 333
復(fù)制代碼

      https://www.gnu.org/software/gaw ... .html#Increment-Ops
    lvalue++
Increment lvalue, returning the old value of lvalue as the value of the expression.

awk ‘++a[$0]==1’ 和上面的代碼作用一樣,你理解了么?


11. 如何打印單雙引號?



  1. awk 'BEGIN {print "single quote --> '\''";print "double quote --> \"" }'
  2. single quote --> '
  3. double quote --> "
復(fù)制代碼



更可靠的的方法如Tim所示:

  1. awk 'BEGIN {print "single quote --> \047";print "double quote --> \042" }'
復(fù)制代碼

12. awk 語句中多個{}是怎么執(zhí)行的?

還是用個例子來說明:



  1. cat file
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5

  7. awk '$1==3{printf "|| "$0}{printf " @@ "$0}{print $0}' file # 這個語句中包含三個action
  8. @@ 11   # 判斷$1==3?否;執(zhí)行 action {printf " @@ "$0};執(zhí)行 action {print $0}
  9. @@ 22   # 判斷$1==3?否;執(zhí)行 action {printf " @@ "$0};執(zhí)行 action {print $0}
  10. || 3 @@ 33  # 判斷$1==3?是,執(zhí)行{print “|| “$0}; 執(zhí)行 action {printf " @@ "$0};執(zhí)行 action {print $0}
  11. @@ 44  # 判斷$1==3?否;執(zhí)行 action {printf " @@ "$0};執(zhí)行 action {print $0}
  12. @@ 55  # 判斷$1==3?否;執(zhí)行 action {printf " @@ "$0};執(zhí)行 action {print $0}
復(fù)制代碼

這樣可以清楚的看出,awk是一行一行讀取文本,然后按照代碼的前后順序執(zhí)行。但如果action中包含next或exit時,有所不同:



  1. awk '$1==3{printf "|| "$0;next}{printf "@@ "$0}{print $0}' file
  2. @@ 11
  3. @@ 22
  4. || 3@@ 44
  5. @@ 55

  6. awk '$1==3{printf "|| "$0;exit}{printf "@@ "$0}{print $0}' file
  7. @@ 11
  8. @@ 22
  9. || 3
復(fù)制代碼


13. FS, OFS, RS, ORS?

最后用圖解的方式說明一下這四個變量:

Picture2.png (38.81 KB, 下載次數(shù): 741)

Picture2.png

評分

參與人數(shù) 9可用積分 +26 信譽積分 +50 收起 理由
方兆國兒 + 10 很給力!
_寒_CU + 10 SS博 ,很給力! 贊一個!
請叫我俊哥哈 + 10 好東西
substr函數(shù) + 10 很給力!
zsszss0000 + 10 贊一個!
xiaopan3322 + 5 很不錯,學習……
expert1 + 10 a
ywlscpl + 6 總結(jié)的很不錯
ly5066113 + 5 善于總結(jié)是一個好習慣,再接再厲!

查看全部評分

論壇徽章:
2
射手座
日期:2014-10-10 15:59:4715-16賽季CBA聯(lián)賽之上海
日期:2016-03-03 10:27:14
2 [報告]
發(fā)表于 2011-04-26 08:41 |只看該作者
多謝Tim哥支持

論壇徽章:
23
15-16賽季CBA聯(lián)賽之吉林
日期:2017-12-21 16:39:27白羊座
日期:2014-10-27 11:14:37申猴
日期:2014-10-23 08:36:23金牛座
日期:2014-09-30 08:26:49午馬
日期:2014-09-29 09:40:16射手座
日期:2014-11-25 08:56:112015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:49:0315-16賽季CBA聯(lián)賽之山東
日期:2017-12-21 16:39:1915-16賽季CBA聯(lián)賽之廣東
日期:2016-01-19 13:33:372015亞冠之山東魯能
日期:2015-10-13 09:39:062015亞冠之西悉尼流浪者
日期:2015-09-21 08:27:57
3 [報告]
發(fā)表于 2011-04-26 08:44 |只看該作者
有幾個地方感覺不是很準確。

6. Awk 語句中可以使用{n,m}這樣的正則么?
可以,不過是一種GNU的擴展,使用方法:gawk -- re-interval

{n,m}這樣的正則在什么版本的awk里都可以使用,并不是GNU的擴展,只不過使用的方式有所不同。

7. BEGIN 和END 到底是怎么一回事?
有時,對于新手可能也會是個問題。簡單說下:
BEGIN {action} : 讀取文本之前進行的操作,所以不可以妄想在BEGIN的{action}中,對文本進行任何操作,或獲取任何文本的信息。

這個說法太絕對了,在BEGIN中可以使用getline函數(shù)來操作文本。

11. 如何打印單雙引號?

這個我更傾向與用八進制數(shù)來表示,利用shell引號的解析來做看起來很混亂,就像變量的引用一樣
  1. awk 'BEGIN {print "single quote --> \047";print "double quote --> \042" }'
復(fù)制代碼

論壇徽章:
0
4 [報告]
發(fā)表于 2011-04-26 08:45 |只看該作者
支持

論壇徽章:
2
射手座
日期:2014-10-10 15:59:4715-16賽季CBA聯(lián)賽之上海
日期:2016-03-03 10:27:14
5 [報告]
發(fā)表于 2011-04-26 08:46 |只看該作者
有幾個地方感覺不是很準確。


{n,m}這樣的正則在什么版本的awk里都可以使用,并不是GNU的擴展,只不過使 ...
ly5066113 發(fā)表于 2011-04-26 08:44



    好的,馬上改正

論壇徽章:
0
6 [報告]
發(fā)表于 2011-04-26 09:03 |只看該作者
好筒子

論壇徽章:
5
2015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亞洲杯之朝鮮
日期:2015-03-13 22:47:33IT運維版塊每日發(fā)帖之星
日期:2016-01-09 06:20:00IT運維版塊每周發(fā)帖之星
日期:2016-03-07 16:27:44
7 [報告]
發(fā)表于 2011-04-26 09:09 |只看該作者
這種分享的精神絕對要支持!

有些地方可能值得商榷,如:

10.
原來,第一個a[$0]的值為空,由于“!”的運算級別高于“+”

++與+是不同的操作符,還有++的優(yōu)先級比!高。

13. 里面的圖示是不是弄反了?

論壇徽章:
2
射手座
日期:2014-10-10 15:59:4715-16賽季CBA聯(lián)賽之上海
日期:2016-03-03 10:27:14
8 [報告]
發(fā)表于 2011-04-26 09:26 |只看該作者
回復(fù) 7# blackold


   圖已更正,黑哥真是火眼

   ++比!級別高的話,!a[$0]++是先執(zhí)行a[$0]++么?那!a[$0]++不應(yīng)該是0么?有點暈,黑哥指點下

論壇徽章:
5
2015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亞洲杯之朝鮮
日期:2015-03-13 22:47:33IT運維版塊每日發(fā)帖之星
日期:2016-01-09 06:20:00IT運維版塊每周發(fā)帖之星
日期:2016-03-07 16:27:44
9 [報告]
發(fā)表于 2011-04-26 09:38 |只看該作者
回復(fù) 8# yinyuemi


    這是前加/后加的區(qū)別,前幾天還說過。

   后加: 先使用變量的值,再自加。

   !a[$0]++ 對這個表達式的求值,它的值與 !a[$0] 相同(先使用變量a[$0]的值),但對表達式求值后 a[$0]會自加。


   圖里面的 RS值前后不一致啊。

論壇徽章:
2
射手座
日期:2014-10-10 15:59:4715-16賽季CBA聯(lián)賽之上海
日期:2016-03-03 10:27:14
10 [報告]
發(fā)表于 2011-04-26 09:47 |只看該作者
回復(fù)  yinyuemi


    這是前加/后加的區(qū)別,前幾天還說過。

   后加: 先使用變量的值,再自加。
  ...
blackold 發(fā)表于 2011-04-26 09:38



    我知道問題出哪里了,我之前“困”在那個運算級別的判斷了,現(xiàn)在弄明白了,多謝黑哥
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP