awk 中的 getline 用法解析

 

轉載請註明出處:http://hi.baidu.com/leejun_2005/blog/item/702d4888928b15a60e2444b4.html

REF: http://bbs.chinaunix.net/thread-108596-1-1.html

1、getline用法簡介:
getline 是awk裏用於輸入重定向的一個函數,他可以從標準輸入/一個管道/文件讀取輸入, 而不只是從當前被處理的文件來處理, 他取得輸入的下一行並給NF,NR,FNR等內製變量置值, 如果找到一條記錄則getline返回1,如果到了文件結束(EOF)則返回0,如果錯誤則返回-1
man bash: search about getline
getline < file sets $0 to the next record from
file. getline x sets variable x instead.
...
In all cases, getline returns 1 for a
successful input, 0 for end of file, and -1 for an error.
awk的 getline語句用於簡單地讀取一條記錄。如果用戶有一個數據記錄類似兩個物理記錄,那麼getline將尤其有用。它完成一般字段的分離(設置字段變量$0 FNR NF NR)。如果成功則返回1,失敗則返回0(到達文件尾)。如果需簡單地讀取一個文件,則可以編寫以下代碼:
例:示例getline的使用
{while(getline==1)
{
#process the inputted fields
}
}

也可以使getline保存輸入數據在一個字段中,而不是通過使用getline variable的形式處理一般字段。當使用這種方式時,NF被置成0,FNR和NR被增值。
用戶也可以使用getline<"filename"方式從一個給定的文件中輸入數據,而不是從命令行所列內容輸入數據。此時,getline將完成一般字段分離(設置字段變量$0和NF)。如果文件不存在,返回-1,成功,返回1,返回0表示失敗。用戶可以從給定文件中讀取數據到一個變量中,也可以用stdin(標準輸入設備)或一個包含這個文件名的變量代替filename。值得注意的是當使用這種方式時不修改FNR和NR。
另一種使用getline語句的方法是從UNIX命令接受輸入,例如下面的例子:

例:示例從UNIX命令接受輸入
{while("who -u"|getline)
{
#process each line from the who command
}
}

當然,也可以使用如下形式:

"command" | getline variable
例如:

/home/lee#awk 'BEGIN{"date"|getline var;split(var,a);print a[4]}'
16:46:26
/home/lee#awk 'BEGIN{getline name<"/dev/tty";print "yourname:"name}'
lee
yourname:lee

getline在不同環境下設置的值:

table-getline-variants summarizes the eightvariants of getline, listing which built-in variables are set by each one.

Variant

Effect

getline

Sets $0, NF, FNR, and NR

getline var

Sets var, FNR, and NR

getline < file

Sets $0 and NF

getline var < file

Sets var

command | getline

Sets $0 and NF

command | getline var

Sets var

command |& getline

Sets $0 and NF. This is a gawk extension

command |& getline var

Sets var. This is a gawk extension



==================================================================================
2、getline 用法舉例:
#awk中getline獲取shell命令的執行結果(不是返回值)
June@~ 21:34:59>
echo |awk '{"echo \"1 + 2\"|bc"|getline v;print v}'
3
June@~ 21:35:02>
注意:awk中使用管道調用shell命令結束後一定要close("cmd")
案例分析請見: http://hi.baidu.com/leejun_2005/blog/item/88f7b9838e794785f703a60b.html

通過在awk內使用管道,可以把shell命令的輸出傳送給awk
$ awk 'BEGIN{ "date" | getline date; print date; }'
Sun Mar 8 22:21:52 2009

#getline的狀態返回值可以被賦值
awk '{if($6!~/6/){tmp=$0}if($6~/6/){c=getline s;if(c==0)s="";print tmp,$0,s}}' file

awk getline接收用戶輸入,有兩種形式:
getline string < "/dev/tty"
getline string < "-"
1)提示用戶輸入參數getline:awk 'BEGIN{print "input sth";getline var <"-" ; print var}' # 其中 "-" 就是標準輸入,很多工具都支持 "-" ,比如tar/cat等。
2)獲取awk腳本的位置參數:awk 'BEGIN{print ARGV[1],ARGV[2]}' a b

getline怎樣保存shell的全部輸出:
awk 'BEGIN{srs=RS;RS="";"ls ./" | getline TMP;RS=srs;print TMP}'

getline直接讀取文件,注意BEGIN是預處理部分,不是action部分,此時還沒有準備處理文件,指針也沒有指向文件第1行,在執行過程中也不會移動文件指針的。簡單的說就是BEGIN部分awk是沒有指針的,此時只有getline指針,awk只在 { } action部分有指針處理。
awk 'BEGIN{while (getline d<"aa") print d}'

seq 10|awk '{getline d<"aa";print d}' #如果getline直接讀一個文件,那麼就是逐行讀取的,因爲此時只有getline指針,而沒有awk指針來處理該文件。


getline打印偶數行:
seq 10 | awk '{getline;print}' # 注意這個和 seq 10 | awk 'BEGIN{while(getline)print}' 有區別!
June@~ 23:07:23>
seq 10 | awk 'i++%2'
2
4
6
8
10
June@~ 23:07:27>

awk getline兩行互換:
seq 10 | awk '{if(getline tmp)print tmp;print}' #一般就是判斷getline的返回值 > 0 的
2
1
4
3
6
5
8
7
10
9

awk中通過system也可執行shell命令:system會返回狀態碼
awk 'BEGIN{ system("ls -l") }'
ps:system裏面也可以利用awk的變量:system("echo ", $1)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章