printf命令詳解


  如果你是一個使用過C語言的程序員,那么你一定會很容易理解printf命令,printf命令模仿了C語言中printf( )函數。

  即使你沒有用過C語言和printf()函數,看完這篇文章以后,你也會很快的掌握printf命令的用法。

  printf命令的主要作用就是輸出文本,不不不,這樣說並不准確,應該說,printf命令的作用是按照我們指定的格式輸出文本。

   而提到輸出文本,你一定會想到另一個常用命令,echo命令,echo命令我們已經總結過,此處不再贅述,我們來對比一下,echo與printf有什么不同

[root@node1 ~]# echo testString
testString
[root@node1 ~]# printf testString
testString[root@node1 ~]# 

   從上述示例中可以看出,在輸出文本時,echo命令會對輸出的文本進行換行,而printf命令則不會對輸出的文本進行換行,那么,如果我們想要利用printf將輸出的文本換行,應該怎么做呢?沒錯,聰明如你一定想到了,使用轉義符\n ,示例如下

[root@node1 ~]# printf "testString\n"
testString

   注意:此處需要加引號

  看到這里你可能會說,這樣多麻煩,還不如直接使用echo命令比較方便,沒錯,如果只是就輸出功能而言,它們並沒有什么不同,但是,剛才已經強調過,printf的優勢在於格式化輸出文本,那么,我們就來通過一個小例子,來見識一下printf的格式化輸出文本的能力。

  假設,我們有一串文本需要輸出,如下

[root@node1 ~]# echo "abc def ghi jkl mno"
abc def ghi jkl mno
[root@node1 ~]# 

   現在我們有一個小需求,就是將上述文本按照空格分段,每段單獨輸出在一行里面。

  當然,有很多方法可以實現上述要求,假設我們並不會使用其他命令,也不是特別會寫腳本,那么我們可能會使用一些笨辦法進行輸出,比如,使用下圖中的命令1或者命令2

 

  注意:命令3 字符沒有使用引號因為如果使用引號則當成一整行字符串了

 

   上述示例中,命令1與命令2在輸出文本時,都使用了轉義字符\n將文本換行了,但是,在寫命令1與命令2的時候,我的內心是崩潰的,因為,上述示例還算簡單,我只是將5段文本分成5行輸出即可,但是,如果是一個100段的文本呢?難道我們要在每一段中都添加一個轉義字符"\n",那我的手不就打殘了,而命令3則不同,我只是通過printf指定了一個固定的"格式",后面的每一段文本都按照指定的格式進行了換行,即使有10000段文本需要換行,我也不用擔心手殘的問題了,從這個小例子中,我們就能體會到printf的格式化能力,上圖中命令3中使用到的"格式"會在后面進行詳細的描述,不要着急。

   說到這里,我發現我們還沒有寫出printf命令的使用語法,printf命令的語法如下

  printf "指定的格式" "文本1" "文本2" "文本3" ......

  還記得剛才的命令3嗎?現在,我們對比着命令3和語法一起看,會更加明了。

 

 

   

  聰明如你一定想到了,上述語法中的每一個"文本"都會被當做參數項傳入printf命令,而每個被傳入的參數都會按照指定的"格式"被"格式化"。

  沒錯,命令3中的"%s\n"即為我們指定的"格式",而后面的每一段字符串,都被當做參數傳入到了printf命令中,並按照我們指定的格式進行了格式化。那么,我們現在來詳細的解釋一下上圖中的"%s\n"是什么意思。

  我們先說說"%s"是什么意思,"%s"是一個"替身演員",我們使用"%s"代替傳入的參數,也就是說, "%s"代替了命令3中的abc,代替了def,代替了ghi,代替了每一個傳入的參數,在我們指定的"格式"中,它代表了每一個傳入的參數,所以,如果我們指定的格式為"%s\n",當abc被當做參數傳入printf命令時,printf就會把"%s\n"中的%s替換成abc,於是,abc就變成了我們指定的格式"abc\n",最終printf輸出的就是格式化后的"abc\n",以此類推,每一段文本都被當做一個參數傳入printf命令,然后按照指定的格式輸出了。

  而"替身演員"只是我給"%s"起的一個外號,它的真名叫"格式替換符",而printf中,"格式替換符"不只有"%s"一種,"%s"代替了每一個傳入的參數,並將他們轉化成了"字符串類型",我們再來認識一個新的替身演員,"%f" ,"%f"也代替了每一個傳入的參數,與"%s"不同的是,"%f"會將每一個傳入的參數轉換成"浮點類型",我們來看一個小例子。

[root@node1 ~]# printf "%s\n" 1 19 18 666
1
19
18
666
[root@node1 ~]# printf "%f\n" 1 19 18 666
1.000000
19.000000
18.000000
666.000000

    上例中,我們分別使用了"%s"替換符和"%f"替換符格式化了相同的內容,但是格式化后的結果卻不同。

  "%f"自動將傳入的數字添加了小數點,將傳入的數字參數替換成了浮點數。

  

  聰明如你一定想到了,我們可以根據傳入參數的不同,使用不同的"格式替換符"去替換。

  那么,還有哪些格式替換符呢?常用的格式替換符總結如下。

%s 字符串

%f 浮點格式(也就是我們概念中的float或者double)

%b 相對應的參數中包含轉義字符時,可以使用此替換符進行替換,對應的轉義字符會被轉義。

%c ASCII字符。顯示相對應參數的第一個字符

%d, %i 十進制整數

%o 不帶正負號的八進制值

%u 不帶正負號的十進制值

%x 不帶正負號的十六進制值,使用a至f表示10至15

%X 不帶正負號的十六進制值,使用A至F表示10至15

%% 表示"%"本身

   說完了"格式替換符",再來說說"轉義字符",剛才的示例中,我們只用到了"\n"這個轉義符,還有很多其他的轉義符,printf中的轉義字符與其他程序中的轉義字符沒有什么不同,此處我們只是總結出來,方便大家使用。printf常用的轉義符如下。

\a 警告字符,通常為ASCII的BEL字符

\b 后退

\c 抑制(不顯示)輸出結果中任何結尾的換行字符(只在%b格式指示符控制下的參數字符串中有效),而且,任何留在參數里的字符、任何接下來的參數以及任何留在格式字符串中的字符,都被忽略

\f 換頁(formfeed)

\n 換行

\r 回車(Carriage return)

\t 水平制表符

\v 垂直制表符

\\ 一個字面上的反斜杠字符,即"\"本身。

\ddd 表示1到3位數八進制值的字符,僅在格式字符串中有效

\0ddd 表示1到3位的八進制值字符

   printf的格式化功能我們還沒有說完,先別急着關閉這個網頁,繼續往下看。

  現在,我們已經會基本的使用printf命令了,但是還有很多東西沒有細聊,在"深入"之前,我們先"淺出"一下,把剛才的知識應用一遍,動手做一些小例子,為后面的知識點打下堅實的基礎。

  假設,我想為每個傳入的參數添加一對"括號",並且括號內側需要有空格,那么我們可以使用如下命令。

[root@node1 ~]# printf "( %s )" 1 19 18 666 ;echo
( 1 )( 19 )( 18 )( 666 )

   注意:加;echo在執行完printf后輸出一個回車

  假設,我們想要將每個傳入的參數使用"制表符"隔開,那么,可以使用如下命令。

[root@node1 ~]# printf "%s\t" 1 19 18 666 ;echo
1	19	18	666	

   剛才的舉例中,我們使用到的"格式"其實很簡單,每個"格式"中都只用到了一個"格式替換符",現在,我們擴展一下,在格式中設置多個"格式替換符"試試,示例如下  

[root@node1 ~]# printf "%s\n" a b c d e f
a
b
c
d
e
f
[root@node1 ~]# printf "%s %s\n" a b c d e f
a b
c d
e f

   看完上圖,聰明如你一定想到了,我們所指定的"格式"中所包含的"格式替換符"的數量,就代表每次格式化的參數的數量,每個"格式替換符"與參數都是一一對應的,上圖中,指定的"格式"中包含兩個"格式替換符",那么printf每次進行"格式化"操作時,就會傳入兩個參數,然后前一個參數對應第一個替換符,后一個參數對應第二個替換符,當本次格式化操作完成以后,再傳入下一波參數,示意圖如下

 

   那么,我們再驗證一遍上述理論,把之前的格式改為如下圖中的模樣

[root@node1 ~]# printf "%s %s %s\n" a b c d e f
a b c
d e f

   按照之前的理論,因為"格式"中包含3個"格式替換符",所以每輪格式化都可以一次性格式化3個參數,於是,第一次格式化操作將"%s %s %s\n"替換成了"a b c\n",第二次格式化操作將"%s %s %s\n"替換成了"d e f\n",格式化后的輸出入上圖所示。

  好了,我們再看一個例子,跟上例其實沒有區別,只是傳入的數據更貼合實際,所以格式化后的數據可讀性更高了。

[root@node1 ~]# printf "%s %s %s\n" 姓名 性別 年齡 古天樂 男 20 小龍女 女 18
姓名 性別 年齡
古天樂 男 20
小龍女 女 18

   如果你跟我一樣,有所謂的強迫症,那么你對上圖中的格式化效果肯定不滿意,上圖中,被格式化以后的數據雖然可讀性更高了,但是並沒有完全對齊,"年齡"字段對應的數字都快跑到"性別"字段里面了,這怎么能忍?其實我就是說說,真忍也就忍了。不過咱們也可以不這么委屈自己,因為printf有能力"滿足"這樣的"需求"。

  我們看看,printf是怎樣拯救強迫症患者的,示例如下。

[root@node1 ~]# printf "%s %s %s\n" 姓名 性別 年齡 古天樂 男 20 小龍女 女 18
姓名 性別 年齡
古天樂 男 20
小龍女 女 18
[root@node1 ~]# printf "%7s %5s %4s\n" 姓名 性別 年齡 古天樂 男 20 小龍女 女 18
 姓名 性別 年齡
古天樂   男   20
小龍女   女   18

   我們只是在原來的"格式替換符"中間加入了特定的數字,貌似顯示效果就比剛才好了一點,起碼年齡字段對應數字與"年齡"兩個字對齊了。那么這些數字是什么意思呢?上圖中第一個"%7s"中間的7表示當前替換符對應的輸出寬度為7個字符寬,如果對應的輸出不足7個字符,則用空格補全,如果輸出的長度超過7個字符,超出的部分也會顯示。同理"%5s"表示當前替換符對應的輸出寬度為5個字符的寬度。而這些數字,我們可以將其稱之為"修飾符",修飾符會對相應的"替換符"進行修飾。

  神馬?看右對齊不順眼,想要左對齊?好吧,滿足你!看下圖

[root@node1 ~]# printf "%-7s %-5s %-4s\n" 姓名 性別 年齡 古天樂 男 20 小龍女 女 18
姓名  性別 年齡
古天樂 男   20  
小龍女 女   18  

   與之前的"格式"相比,只是在原來的修飾符前面加入了"-","-"表示左對齊,默認不加"-"時表示右對齊,其實"-"也是修飾符。

  除了數字和"-",還有另一種修飾符,就是"+"

  "+"可不代表右對齊,因為我們前面已經說過,不加"-"修飾符的時候,默認就是右對齊。那么"+"修飾符表示什么意思呢?看下圖你就會明白。

[root@node1 ~]# printf "靈寵名稱 體溫\n";printf "%10s %5d\n" 烈火獸 180 冰晶獸 -70 
靈寵名稱 體溫
 烈火獸   180
 冰晶獸   -70
[root@node1 ~]# printf "靈寵名稱 體溫\n";printf "%10s %+5d\n" 烈火獸 180 冰晶獸 -70 
靈寵名稱 體溫
 烈火獸  +180
 冰晶獸   -70

   如上圖所示,在默認沒有添加"+"作為修飾符時,烈火獸的體溫輸出為180,而使用了"+"修飾符以后,烈火獸的體溫輸出為+180,看到這里你應該明白了,當替換符對應的參數為數字時,可以使用"+"作為修飾符,輸出"正數"前面的"正號"。

  現在我們已經學會了3種修飾符

  "數字"

  "+"

  "-"

  其實數字修飾符還有另外的一些特殊用法,如下圖所示。

[root@node1 ~]# printf "靈寵名稱 體溫\n";printf "%-10s %-12f\n" 烈火獸 180 冰晶獸 -70 
靈寵名稱 體溫
烈火獸  180.000000  
冰晶獸  -70.000000  
[root@node1 ~]# printf "靈寵名稱 體溫\n";printf "%-10s %-12.3f\n" 烈火獸 180 冰晶獸 -70 
靈寵名稱 體溫
烈火獸  180.000     
冰晶獸  -70.000     

   上圖中,第一條命令的數字修飾符為12,表示對應的替換符"%f"的輸出寬度為12個字符,第二條命令的數字修飾符為12.3 ,表示對應的替換符"%f"的輸出寬度為12個字符,並且小數點的精度為3。

  沒錯,當替換符為"%f"時,如果數字修飾符帶有小數點,則數字修飾符小數點后的數字表示對應小數精度。

  而當格式替換符為"%d"時,如果數字修飾符帶有小數點,則數字修飾符小數點后的數字表示整數的長度,長度不夠時,高位用0補全,如下圖所示。

[root@node1 ~]# printf "靈寵名稱 體溫\n";printf "%-10s %-12d\n" 烈火獸 180 冰晶獸 -70 
靈寵名稱 體溫
烈火獸  180         
冰晶獸  -70         
[root@node1 ~]# printf "靈寵名稱 體溫\n";printf "%-10s %-12.5d\n" 烈火獸 180 冰晶獸 -70 
靈寵名稱 體溫
烈火獸  00180       
冰晶獸  -00070      

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM