首頁 > 軟體

awk中的變數

2020-06-16 18:03:07

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

--------------------------------------分割線 --------------------------------------

AWK簡介及使用範例 http://www.linuxidc.com/Linux/2013-12/93519.htm

AWK 簡介和例子 http://www.linuxidc.com/Linux/2012-12/75441.htm

Shell指令碼之AWK文字編輯器語法 http://www.linuxidc.com/Linux/2013-11/92787.htm

正規表示式中AWK的學習和使用 http://www.linuxidc.com/Linux/2013-10/91892.htm

文字資料處理之AWK 圖解 http://www.linuxidc.com/Linux/2013-09/89589.htm

如何在Linux中使用awk命令 http://www.linuxidc.com/Linux/2014-10/107542.htm

文字分析工具-awk  http://www.linuxidc.com/Linux/2014-12/110939.htm

--------------------------------------分割線 --------------------------------------

本文永久更新連結地址http://www.linuxidc.com/Linux/2015-04/115781.htm


IT145.com E-mail:sddin#qq.com