awk中的變數

jeanron100發表於2015-04-01
awk和sed結合起來,對於檔案的橫向縱向處理幾乎是全方位的,可以算是文字處理中的大招了。當然awk這一強大的分本處理工具也不是浪得虛名,功能豐富,學習週期也要長些,不是一個Help文件就能說完的。學習awk可以算得上重新學習一門程式語言,因為裡面的東西確實太多了。我們就按部就班,循序漸進,先來說說awk中的變數。
關於awk中的變數,有內建變數和自定義變數。
內建變數如果細分,有資料欄位和資料行變數,資料變數,可能看概念不好理解。我們一個一個說明。
資料欄位和資料行變數主要有
FIELDWIDTHS  會根據欄位的長度來劃分,比如20150401.223300 如果我們指定FIELDWIDTHS為3 5  3  4  則輸出為201 50401 .22 3300
FS   這個是輸入欄位的分隔符,比如  11,12,13  如果指定FS為,  就會把11,12,13分隔為 11  12  13
OFS 這個是輸出欄位的分隔符,比如 11,12,13 如果我們按照,分隔,資料會為11 12 13,我們指定OFS為“--”,則輸出為11--12--13
RS 這個是輸入資料行的分隔符,使用的場景較為特殊,在下面透過例子來說明。
ORS 這個是輸出資料行的分隔符,使用的場景較為特殊,透過例子來說明。
我們指定一個檔案 a.lst,還是舉個pm2.5的例子。以下是近些天的pm2.5的資料
2015 03 30 100
2015 03 31 150
2015 04 01 70

? awk 'BEGIN{FS=" "}{print $1 $2 $3}' a.lst
20150330
20150331
20150401

注意下面兩種寫法的差別。
? awk 'BEGIN{FS=" " ;OFS="--"}{print $1 $2 $3}' a.lst
20150330
20150331
20150401
? awk 'BEGIN{FS=" " ;OFS="--"}{print $1,$2,$3}' a.lst
2015--03--30
2015--03--31
2015--04--01

關於RS和ORS的使用可以使用下面的例子。
假設我們存在下面的檔案,每隔3行資料就來一個空行。我們可以選擇性的擷取資料欄位的值
 ? cat a.lst
2015line1 03 30 100
2015 03 31 150
2015 04 01 70

2015line2 03 30 100
2015 03 31 150
2015 04 01 70

2015line3 03 30 100
2015 03 31 150
2015 04 01 70
? awk 'BEGIN{FS="\n"; RS=""}{print $1,$3}' a.lst   --這個地方,我們使用RS來分隔資料行,以空行為分界,在這個基礎上按照回車劃分每一列資料。
2015line1 03 30 100 2015 04 01 70
2015line2 03 30 100 2015 04 01 70
2015line3 03 30 100 2015 04 01 70
這樣就把第1行,第3行的資料整合到了一起。按照這個規律下面的資料也是這樣的形式。

如果使用ORS來,結果會大不相同,我們以“--”作為輸出的分隔符。
? awk 'BEGIN{FS="\n"; ORS="----"}{print $1,$3}' a.lst
2015line1 03 30 100 ----2015 03 31 150 ----2015 04 01 70 ---- ----2015line2 03 30 100 ----2015 03 31 150 ----2015 04 01 70 ---- ----2015line3 03 30 100 ----2015 03 31 150 ----2015 04 01 70 ---- ---- ----  


對於資料變數,可能使用的地方相對要少一些。內建變數比如:
ARGC 代表當前命令列的引數個數
ARGV   包含命令列引數的陣列
ENVIRON 代表當前shell環境變數和值組成的關聯陣列
NF 代表資料檔案中的欄位總數
NR  是已處理的輸入資料行數目
舉幾個例子。
 ? awk 'BEGIN{print ARGC,ARGV[0],ARGV[1]}' a.lst
2 awk a.lst
其中ARGC是命令列的引數個數,可以看到兩個引數的值分別為awk和a.lst,下標從0開始

 ? awk '{print ENVIRON["HOME"] ,ENVIRON["PATH"]}' a
/home/mobaxterm /bin:/bin:/drives/c/WINDOWS:/drives/c/WINDOWS/system32


自定義變數的部分是平時使用頻率比較高的,這個部分的靈活性還是很大的。基本上有以下幾個場景。
在指令碼中給變數賦值,在命令列上給變數賦值

指令碼中給變數賦值,比如我們指定一個變數test,然後初始化兩次,變數值都會動態變化
? awk '
> BEGIN{
> test="first_try"
> print test
> test="second_try"
> print test
> }'
first_try
second_try

對於命令列中給變數賦值,可以這麼理解。
 ? cat a.lst
2015line1 03 30 100
2015 03 31 150
2015 04 01 70

? awk 'begin{FS=" "}{print $n}' n=3 a.lst
30
31
01
這種情況下,會根據設定的變數值,動態賦予n=3

如果需要傳遞shell變數的值,可以透過-v選項來實現
? awk -v n=3 '{print "this is a test",n}' a
this is a test 3

test=aaaaa
echo $test
aaaa
? awk -v t=$test '{print "testing value:" t}' a.lst
testing value:aaaa
testing value:aaaa
testing value:aaaa


                   








來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-1482374/,如需轉載,請註明出處,否則將追究法律責任。

相關文章