回到: "Linux系列文章" "Shell系列文章" "Awk系列文章" 輸出操作 awk可以通過print、printf將數據輸出到標準輸出或重定向到文件。 print 逗號分隔要列印的欄位列表,各欄位都 會自動轉換成字元串格式 ,然後通過預定義變數OFS(output field separa ...
回到:
輸出操作
awk可以通過print、printf將數據輸出到標準輸出或重定向到文件。
print elem1,elem2,elem3...
print(elem1,elem2,elem3...)
逗號分隔要列印的欄位列表,各欄位都會自動轉換成字元串格式,然後通過預定義變數OFS(output field separator)的值(其預設值為空格)連接各欄位進行輸出。
$ awk 'BEGIN{print "hello","world"}'
hello world
$ awk 'BEGIN{OFS="-";print "hello","world"}'
hello-world
print要輸出的數據稱為輸出記錄,在print輸出時會自動在尾部加上輸出記錄分隔符,輸出記錄分隔符的預定義變數為ORS,其預設值為\n
。
$ awk 'BEGIN{OFS="-";ORS="_\n";print "hello","world"}'
hello-world_
括弧可省略,但如果要列印的元素中包含了特殊符號>
,則必須使用括弧包圍(如print("a" > "A")
),因為它是輸出重定向符號。
如果省略參數,即print;
等價於print $0;
。
print輸出數值
print在輸出數據時,總是會先轉換成字元串再輸出。
對於數值而言,可以自定義轉換成字元串的格式,例如使用sprintf()進行格式化。
print在自動轉換數值(專指小數)為字元串的時候,採用預定義變數OFMT(Output format)定義的格式按照sprintf()相同的方式進行格式化。OFMT預設值為%.6g
,表示有效位(整數部分加小數部分)最多為6。
$ awk 'BEGIN{print 3.12432623}'
3.12433
可以修改OFMT,來自定義數值轉換為字元串時的格式:
$ awk 'BEGIN{OFMT="%.2f";print 3.99989}'
4.00
# 格式化為整數
$ awk 'BEGIN{OFMT="%d";print 3.99989}'
3
$ awk 'BEGIN{OFMT="%.0f";print 3.99989}'
4
printf
printf format, item1, item2, ...
格式化字元:
修飾符:均放在格式化字元的前面
N$ N是正整數。預設情況下,printf的欄位列表順序和格式化字元
串中的%號順序是一一對應的,使用N$可以自行指定順序。
printf "%2$s %1$s","world","hello"輸出hello world
N$可以重覆指定,例如"%1$s %1$s"將取兩次第一個欄位
寬度 指定該欄位占用的字元數量,不足寬度預設使用空格填充,超出寬度將無視。
printf "%5s","ni"輸出"___ni",下劃線表示空格
- 表示左對齊。預設是右對齊的。
printf "%5s","ni"輸出"___ni"
printf "%-5s","ni"輸出"ni___"
空格 針對於數值。對於正數,在其前添加一個空格,對於負數,無視
printf "% d,% d",3,-2輸出"_3,-2",下劃線表示空格
+ 針對於數值。對於正數,在其前添加一個+號,對於負數,無視
printf "%+d,%+d",3,-2輸出"+3,-2",下劃線表示空格
# 可變的數值首碼。對於%o,將添加首碼0,對於%x或%X,將添加首碼0x或0X
0 只對數值有效。使用0而非預設的空格填充在左邊,對於左對齊的數值無效
printf "%05d","3"輸出00003
printf "%-05d","3"輸出3
printf "%05s",3輸出____3
' 單引號,表示對數值加上千分位逗號,只對支持千分位表示的locale有效
$ awk "BEGIN{printf \"%'d\n\",123457890}"
123,457,890
$ LC_ALL=C awk "BEGIN{printf \"%'d\n\",123457890}"
123457890
.prec 指定精度。在不同格式化字元下,精度含義不同
%d,%i,%o,%u,%x,%X 的精度表示最大數字字元數量
%e,%E,%f,%F 的精度表示小數點後幾位數
%s 的精度表示最長字元數量,printf "%.3s","foob"輸出foo
%g,%G 的精度表示表示最大有效位數,即整數加小數位的總數量
sprintf()
sprintf()採用和printf相同的方式格式化字元串,但是它不會輸出格式化後的字元串,而是返回格式化後的字元串。所以,可以將格式化後的字元串賦值給某個變數。
awk '
BEGIN{
a = sprintf("%03d", 12.34)
print a # 012
}
'
重定向輸出
print[f] something >"filename"
print[f] something >>"filename"
print[f] something | "Shell_Cmd"
print[f] something |& "Shell_Cmd_Coprocess"
>filename
時,如果文件不存在,則創建,如果文件存在則首先截斷。之後再輸出到該文件時將不再截斷。
awk中只要不close(),任何文件都只會在第一次使用時打開,之後都不會再重新打開。
awk '{print $2 >"name.txt";print $4 >"name.txt"}' a.txt
>>filename
時,將追加數據,文件不存在時則創建。
print[f] something | Shell_Cmd
時,awk將創建一個管道,然後啟動Shell命令,print[f]產生的數據放入管道,而命令將從管道中讀取數據。
# 例1:
awk '
NR>1{
print $2 >"name.unsort"
cmd = "sort >name.sort"
print $2 | cmd
#print $2 | "sort >name.sort"
}
END{close(cmd)}
' a.txt
# 例2:awk中構建Shell命令,通過管道交給shell執行
awk 'BEGIN{printf "seq 1 5" | "bash"}'
print[f] something |& Shell_Cmd
時,print[f]產生的數據交給Coprocess。之後,awk再從Coprocess中取回數據。這裡的|&
有點類似於能夠讓Shell_Cmd後臺非同步運行的管道。
stdin、stdout、stderr
awk重定向時可以直接使用/dev/stdin
、/dev/stdout
和/dev/stderr
。還可以直接使用某個已打開的文件描述符/dev/fd/N
。
例如:
awk 'BEGIN{print "something OK" > "/dev/stdout"}'
awk 'BEGIN{print "something wrong" > "/dev/stderr"}'
awk 'BEGIN{print "something wrong" | "cat >&2"}'
awk 'BEGIN{getline < "/dev/stdin";print $0}'
$ exec 4<> a.txt
$ awk 'BEGIN{while((getline < "/dev/fd/4")>0){print $0}}'