標籤:blog 使用 檔案 ar 資料 html log amp sp
【著作權聲明:轉載請保留出處:blog.csdn.net/gentleliu。Mail:shallnew at 163 dot com】
awk有許多內建變數用來設定環境資訊。這些變數可以被改變。下面是awk內建變數:
ARGC 命令列參數個數
ARGV 命令列參數排列
ENVIRON 支援隊列中系統內容變數的使用
FILENAME a w k瀏覽的檔案名稱
FNR 瀏覽檔案的記錄數
FS 設定輸入欄位分隔字元,等價於命令列 - F選項
NF 瀏覽記錄的域個數
NR 已讀的記錄數
OFS 輸出域分隔字元
ORS 輸出記錄分隔字元
RS 控制記錄分隔字元
1、 內建變數
NF支援記錄域個數,在記錄被讀之後再設定,也就是讀入的每一行根據設定的分割符號分割出來的域的個數。也叫做“欄位數量”變數。awk 會自動將該變數設定成當前行中的欄位數量。
NR查看當前正在操作的行號。
FILENAME 記錄當前正在操作檔案的檔案名稱。
現在我們取出檔案group_file1的行號以及每一行域數量。
awk '{print NR, NF}' group_file1 1 32 33 34 45 3
現在我們傳入awk兩個檔案,去除當前操作的檔案名稱以及NR、NF資訊:
# awk '{print FILENAME,NR, NF}' group_file1 group_file2group_file1 1 3group_file1 2 3group_file1 3 3group_file1 4 4group_file1 5 3group_file2 6 1group_file2 7 1group_file2 8 1group_file2 9 1group_file2 10 1
可見NR並非當前行在檔案中的行號,而是整個被操作檔案清單被操作的行數量,沒處理一行該值會加一。
有了NF、NR之後我們的操作又變得更加靈活了。我們可以再加入條件判斷和Regex,下面列印欄位數量為3並且第三欄位匹配98的行:
# awk '{if (NF == 3 && $3~/98/) print}' group_file1wireshark x 987usbmon x 986jackuser x 985
我們可以將當前絕對路徑傳入,分析出目前的目錄名稱:
# pwd/home/Myprojects/shell_text_filter/awk# pwd | awk -F"/" '{print $NF }'awk
類似地,傳入檔案絕對路徑,也可以分析出檔案名稱。
OFS 可以使列印的單欄位之間列印 OFS 變數,我們可以方便地重新定義 OFS,這樣 awk 將插入我們中意的欄位分隔符號。沒有設定OFS,預設為空白。
# awk 'BEGIN{OFS=" - "}{print $1, $3}' group_file1 wireshark - 987usbmon - 986jackuser - 985vboxusers - 984aln – 1001
ORS輸出記錄分隔字元,通過設定預設為換行("\n") 的 OFS,我們可以控制在 print 語句結尾自動列印的字元,預設 ORS 值會使 awk 在新行中輸出每個新的 print 語句。如果想使輸出的間隔翻倍,可以將 ORS 設定成 "\n\n"。或者,如果想要用單個空格分隔記錄(而不換行),將 ORS 設定成 " "。比如如下兩個檔案:
# cat 11 2 3 4 5# cat 26 7 8 9 0
我們想將其內容串連到一行,可以這樣使用:
# awk 'BEGIN{ORS=" "}{print}' 1 21 2 3 4 5 6 7 8 9 0
下面將group_file1檔案每行用符號”-”連結在一起,:
# awk 'BEGIN{ORS=" - "}{print}END{ORS="\n";print "\n"}' group_file1wireshark x 987 - usbmon x 986 - jackuser x 985 - vboxusers x 984 allen - aln x 1001 -
RS變數控制記錄分隔字元,通過RS 變數告訴 awk 目前記錄什麼時候結束,新記錄什麼時候開始。我們可以將一行記錄通過設定RS變數將其分成多行記錄來分析。比如我們將上面一條awk命令執行結果哪一行傳入新的awk,通過設定RS將其分割成多行來分析:
# awk 'BEGIN{ORS=" - "}{print}END{ORS="\n";print "\n"}' group_file1 | awk 'BEGIN{RS=" - "}{print $1}'wiresharkusbmonjackuservboxusersaln
2、 一般變數
在awk中,設定有意義的網域名稱是一種好習慣一般的變數名設定方式為 var = $n,這裡var 為調用的域變數名, n為實際域號。
# awk '{name=$1;id=$3;if (id==985)print name}' group_file1jackuser#
通常在BEGIN部分賦值是很有益的,可以在awk運算式進行改動時減少很多麻煩。比如我們想列印id大於1000的使用者組名:
# awk 'BEGIN{id=1000}{if($3>id)print $1}' group_file1 Aln
awk通過設定資料欄位值並輸出實現修改檔案資料欄位,當在awk中修改任何資料欄位時,實際輸入檔案是不可修改的,修改的只是儲存在緩衝裡的awk複本。如果我們修改原檔案時,需要awk將修改後的內容輸出到檔案,然後在重新命名為原檔案。
# awk '{if($1=="aln")$3=$3-1; print $1,$2,$3}' group_file1 wireshark x 987usbmon x 986jackuser x 985vboxusers x 984aln x 1000
同樣,增加、減少、修改欄位均可以有同樣的操作。
Awk對每行數值進行統計得出結果很方便:
# awk 'BEGIN{total=0}{total+=$3}END{print "total="total}' group_file1 total=4943
通過上面這個例子,我們想到可以寫一個指令碼來實現統計當前檔案下面所有檔案的大小之和,下面就是這樣一個指令碼:
#!/bin/shls -al | awk 'BEGIN { total=0}{ if (/^[^d]/) { #不統計目錄 total += $5 print $1"\t"$5 }}END { print "total size: " total}'
shell文本過濾編程(四):awk內建變數及一般變數