738 瀏覽數

Linux command – awk 的內建變數

透過 sed 與 awk 都可以把文件做過濾和轉換成新的輸出內容.不過 sedhttp://benjr.tw/97129 適合用於一整行的資料處理,而 awk 則比較適合將一整行做多個 欄位(Field) 的資料處理.先來看看 awk 的幾個範例.

# mawk  [-W  option]  [-F value] [-v var=value] [--] 'program text' [file...]

awk 是 mawk 的連結,兩種方式都可以下指令.

前面 http://benjr.tw/97139 有提到 OFS , ORS 他們是內建的變數,他們所代表的意思如下:

  • OFS 代表的意思 inserted between fields on output, 等同 = ” “.
  • ORS 代表的意思 terminates each record on output, 等同 = “\n” (newline)

還有其他相關變數名稱下面繼續說明.
OFMT
代表的意思 format for printing numbers; 主要是將數字輸出時的格式,預設格式為 “%.6g” 代表整數與小數點只保留 6個數字,OFMT 可以自訂.
下面範例就是將 pi 數字輸出時的格式設定.

root@ubuntu:~# cat OFMT.awk 
BEGIN {
    pi=3.14159265359;
    print "Default OFMT:", pi;
    OFMT="%.4g";
    print "%.4g OFMT:", pi;
    print "---using f---";
    OFMT="%.0f";
    print "%.0f OFMT:", pi;
    OFMT="%.3f";
    print "%.3f OFMT:", pi;
}

ANSI C format

  • %c char single character
  • %d (%i) int signed integer
  • %e (%E) float or double exponential format
  • %f float or double signed decimal
  • %g (%G) float or double use %f or %e as required
  • %o int unsigned octal value
  • %p pointer address stored in pointer
  • %s array of char sequence of characters
  • %u int unsigned decimal
  • %x (%X) int unsigned hex value
root@ubuntu:~# awk -f OFMT.awk
Default OFMT: 3.14159
%.4g OFMT: 3.142
---using f---
%.0f OFMT: 3
%.3f OFMT: 3.142

FILENAME – 目前處理資料的檔案名稱.
FNR – (File Number of Field) 目前處理資料檔案的第幾行 .
下面範例會輸出 檔案名稱 (FILENAME) 以及 FNR 目前處理資料檔案的第幾行

root@ubuntu:~# awk 'END{print "Filename:" FILENAME , "\tCurrent Line:" FNR }' /etc/passwd 
Filename:/etc/passwd 	Current Line:41

沒有 END 時,Print 會列印出每一行處理的資料,使用 END 時只會在資料讀取處理完畢後,執行一次.(關於 awk 的程式結構 請參考 http://benjr.tw/97423).

NR – (Number of Record) 目前處理的資料的第幾行.
下面範例排除特定列 (第2~5列) ,! 等同 not

root@ubuntu:~# ls -l | nl | awk '!(NR>=2 && NR<=5){print $0}'
     1	total 28
     6	-rw-r--r-- 1 root root    5 Jul 10 00:23 text1.txt
     7	-rw-r--r-- 1 root root    5 Jul 10 00:26 text2.txt
     8	-rwxr-xr-x 1 root root  106 Jul 10 01:20 while.sh

NF – (Number of Field) 目前行資料中有幾個 欄位(Field) 的資料.
下面範例使用 ll 來當資料,ll 輸出的第一行的資料是 total # ,所以只有兩個欄位(Field) 的資料.

root@ubuntu:~# ll | awk '{print "Line:"NR "\tColumn:"NF}'
Line:1	Column:2
Line:2	Column:9
Line:3	Column:9
Line:4	Column:9
Line:5	Column:9
Line:6	Column:9
Line:7	Column:9
Line:8	Column:9
Line:9	Column:9
Line:10	Column:9
Line:11	Column:9
Line:12	Column:9

FS – (Fields splits) 預設的欄位區分是以 空白或是 tab 做分隔,要改成其他如 冒號 “:” 來作欄位的分隔時就需要設定 FS 變數.
下面範例處理 /etc/passwd ,並定義了 FS (Fields splits) 為 “:” , \t (tab) , $1 代表第一欄資料

root@ubuntu:~# awk '{FS=":"} {print "User:\t"$1}' /etc/passwd
User:	root:x:0:0:root:/root:/bin/bash
User:	daemon
User:	bin
User:	sys
User:	sync
User:	games
User:	man
User:	lp
User:	mail
User:	news
User:	uucp

第一行沒有處理到, awk 在執行時就會先把第一行的資料讀取進來等待處理,所以 FS 的定義必須透過 BEGIN{} ,所定義的內容只會執行一次. (關於 awk 的程式結構 請參考 http://benjr.tw/97423 ). .

root@ubuntu:~# awk 'BEGIN{FS=":"} {print "User:\t"$1}' /etc/passwd
User:	root
User:	daemon
User:	bin
User:	sys
User:	sync
User:	games
User:	man
User:	lp
User:	mail
User:	news
User:	uucp

其他可用變數名稱
ARGC – number of command line arguments.
ARGV – array of command line arguments, 0..ARGC-1.
CONVFMT – format for internal conversion of numbers to string.
ENVIRON – array indexed by environment variables. An environment string, var=value is stored as ENVIRON[var] = value.
RLENGTH – length set by the last call to the built-in function,match().
RS – input record separator,.
RSTART – index set by the last call to match().
SUBSEP – used to build multiple array subscripts.

發表迴響