如果你是一個使用過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