精通awk系列(13):print、printf、sprintf和重定向


回到:linux


輸出操做

awk能夠經過print、printf將數據輸出到標準輸出或重定向到文件。shell

print

print elem1,elem2,elem3...
print(elem1,elem2,elem3...)

逗號分隔要打印的字段列表,各字段都會自動轉換成字符串格式,而後經過預約義變量OFS(output field separator)的值(其默認值爲空格)鏈接各字段進行輸出。bash

$ 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")),由於它是輸出重定向符號。3d

若是省略參數,即print;等價於print $0;code

print輸出數值

print在輸出數據時,老是會先轉換成字符串再輸出。orm

對於數值而言,能夠自定義轉換成字符串的格式,例如使用sprintf()進行格式化。blog

print在自動轉換數值(專指小數)爲字符串的時候,採用預約義變量OFMT(Output format)定義的格式按照sprintf()相同的方式進行格式化。OFMT默認值爲%.6g,表示有效位(整數部分加小數部分)最多爲6。字符串

$ awk 'BEGIN{print 3.12432623}'
3.12433

能夠修改OFMT,來自定義數值轉換爲字符串時的格式:get

$ 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}}'
相關文章
相關標籤/搜索