shell腳本中printf小節

 printf命令模仿C程序庫(library)裏的printf()庫程序library routine)。它幾乎複製了

該函數的所有功能。不過在Shell層級的版本上,會有些差異。由於printf的行爲是由POSIX

標準所定義,因此使用printf的腳本比使用echo移植性好

如同echo命令,printf命令可以輸出簡單的字符串:

[root@master ~]#printf "Hello, Shell\n"
Hello, Shell
[root@master ~]#

你應該可以馬上發現,最大的不同在於:printf不像echo那樣會自動提供一個換行符號。你必須顯式

地將換行符號指定成\n


printf命令的完整語法有兩個部分:

printf format-string [arguments...]

第一部分爲描述格式規格的字符串,用來描述輸出的排列方式,最好爲此字符串加上引號。此字符

串包含按字面顯示的字符以及格式聲明,格式聲明時特殊的佔位符,用來描述如何顯示相應的參數。

第二部分是與格式聲明相對應的參數列表,例如一系列的字符串或變量值。格式聲明由兩部分組成:

百分比符號(%)和指示符。最常用的格式指示符有兩個%s用於字符串,而%d用於十進制整數


格式字符串中,一般字符會按字面顯示。轉義序列則像echo那樣,解釋後再輸出成相應的字符。格

式聲明以%符號開頭,並以定義的字母集中的一個來結束,用來控制相應參數的輸出。例如%s用於

字符串的輸出:

[root@master ~]# printf "The first program always prints'%s,%d\n'" Hello Shell

輸出結果爲:

-bash: printf: Shell: invalid number
The first program always prints 'Hello,0

'[root@master ~]#

當嘗試以%d的格式來顯示字符串Shell時,會發現有警告,提示Shell爲無效的數字,此時會打印出

默認值0;從這個試驗中可以看出來:%s, %s兩側的單引號''並不是必須的。


printf的轉義序列

序列                     說明

\a                        警告字符,通常爲ASCIIBEL字符

\b                       後退

\c                       抑制(不顯示)輸出結果中任何結尾的換行字符(只在%b格式指示符控制下的

                         參數字符串中有效),而且,任何留在參數裏的字符、任何接下來的參數以及

                         任何留在格式字符串中的字符,都被忽略

\f                      換頁(formfeed

\n                    換行

\r                      回車(Carriage return

\t                      水平製表符

\v                    垂直製表符

\\                      一個字面上的反斜槓字符

\ddd                表示13位數八進制值的字符。僅在格式字符串中有效

\0ddd              表示13位的八進制值字符

 

默認情況下,轉義序列只在格式字符串中會被特別對待,也就是說,如果轉義序列出現在參數列表

的字符串中,將不會被解釋

[root@master ~]#printf "a string, no processing:<%s>\n" "A\nB"

當你使用%b格式指示符時,printf會解釋參數字符串裏的轉義序列:

[root@master ~]#printf "a string, no processing:<%b>\n" "A\nB"

無論時在格式字符串內還是在使用%b所打印的參數字符串裏,大部分的轉義序列都是被相同對待。

無論如何,\c\0ddd只有搭配%b使用纔有效,而\ddd只有在格式字符串裏纔會被解釋

 

現在來試試這些轉義序列的效果

\a     警告字符,通常爲ASCIIBEL字符

ASCII中的BEL代表的是beep,如果你在終端輸入:

[root@master ~]#printf "test \a"
test [root@master ~]#

應該會聽到一聲beep。在我的電腦上前兩天還能聽到,今天測試時沒有聲音了,可能是系統的

設定有改變。


\b     後退

首先新建一個名爲“sh_printf_b.sh”的文檔,內容如下:

#! /bin/bash

printf "1";

sleep 1;

printf "\b";

sleep 1;

printf "2";

sleep 1;

printf "\b";

sleep 1;

printf "3";

sleep 1;

printf "\n"

其運行結果如下圖所示:

結果如下圖顯示,不過每次只是出現一個數字,先是出現1,並且光標在1的右邊;接着還是1,光標在1上面;

然後是2,光標在2的右邊;接着還是2,光標在2的右邊;然後是3,光標在3的右邊;然後光標還是在3的右邊跳動一下立馬就退出了!


\c    抑制(不顯示)輸出結果中任何結尾的換行字符(只在%b格式指示符控制下的

      參數字符串中有效),而且,任何留在參數裏的字符、任何接下來的參數以及

      任何留在格式字符串中的字符,都被忽略

\c要與%b配合使用,請參考下圖,其中%b兩側的尖括號並不是必須的:

[root@master ~]# printf "123<%s>\n" "456" 
123<456>

[root@master ~]# printf "123%b\n" "\c456"   \c 抑制(不顯示)輸出結果中任何結尾的換行字符】
123[root@master ~]#

[root@master ~]# printf "123%b\n" "\n456" 【只在%b格式指示符控制下的參數字符串中有效】
123
456

[root@master ~]# printf "123%b\n" "456" "\c213" 【因爲有兩個參數,第二個沒有說明就不處理】
123456
[root@master ~]#
[root@master ~]# printf "123%s%b\n" "\c456" 【後面如果還有參數則被忽略】
123\c456
[root@master ~]# printf "123%s%b\n" "\c456" "\c213" 【後面的那個"\c213"被忽略了】
123\c456[root@master ~]#

[root@master ~]# printf "123%s\n%b\n" "\c456" "\c213"【這裏多了個\n效果就不一樣了】
123\c456
[root@master ~]#


\f                      換頁(formfeed

在我係統上的效果如下:

[root@master ~]# printf "123\f456\n"
123
   456
[root@master ~]#


\n                     換行  


\r                      回車(Carriage return

創建一個名爲“sh_printf_r.sh”的文檔,內容如下:

#! /bin/bash

printf "111111111";

sleep 1;

printf "\r";

printf "2";

sleep 1;

printf "2";

sleep 1;

printf "2";

sleep 1;

printf "2";

sleep 1;

printf "2";

sleep 1;

printf "2";

sleep 1;

printf "\r"

sleep 1;

printf "3";

sleep 1;

printf "3";

sleep 1;

printf "3";

sleep 1;

printf "\n"

其運行效果如下圖所示:
每次只出現一行,並且一行出現9個數字,注意光標的移動,黃色的是光標每次執行所處的位置;
 

 

\t                      水平製表符

\v                     垂直製表符

\\                      一個字面上的反斜槓字符

[root@master ~]# printf "\\101\n"
A
[root@master ~]#

由此我們可以知道輸出的是ASCII碼

printf格式指示符

項目     說明

%b          相對應的參數被視爲含有要被處理的轉義序列之字符串

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

%d, %i    十進制整數

%e          浮點格式

%E          浮點格式

%f           浮點格式

%g          %e%f轉換,看哪一個較短,則刪除結尾的零

%G          %E%f轉換,看哪一個較短,則刪除結尾的零

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

%s           字符串

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

%x          不帶正負號的十六進制值,使用af表示1015

%X          不帶正負號的十六進制值,使用AF表示1015

%%         字面意義的%

根據POSIX標準:浮點格式%e%E%f%g%G是“不需要被支持”。

這是因爲awk支持浮點預算,且有它自己的printf語句。這樣Shell程序中

需要將浮點數值進行格式化的打印時,可使用小型的awk程序實現。然而,內建

bashksh93zsh中的printf命令都支持浮點格式


printf命令可用來指定輸出字段的寬度以及進行對其操作。爲實現此目的,接在%後

面的格式表達式可採用三個可選用的修飾符(modifier)以及前置的格式指示符(

format specifier):

     %flags width.precision format-specifier

輸出字段的width爲數字值。指定字段寬度時,字段的內容默認爲向右對齊,如果你希望

文字向左靠,必須指定-標誌。這樣:“%-20s”會在一個有20個字符寬度的字段裏,輸出

一個向左對齊的字符串。如果字符串少於20個字符,則字段將以空白填滿。下面的例子裏,

|是輸出,以表示字段的實際寬度。第一個例子爲向右對齊文字:


下一個例子則爲向左對齊文字:

precision修飾符是可選用的。對十進制或浮點數值而言,它可以控制數字出現於結果中的位數。
對於字符串值而言,它控制將要打印的字符串的最大字符數。具體的含義會因格式指示符而有不
同,如下所示:

精度的意義
轉換                                        精度含義
%d,%i,%o,%u,%x,%X           要打印的最小位數。當值的位數小於此數字時,會在前面補零。
                                             默認精度(precision)爲1
%e,%E                                要打印的最小位數。當值的位數小於此數字時,會在小數點後面
                                             補零,默認精度爲6.精度爲0時則表示不顯示小數點
%f                                         小數點右邊的位數
%g,%G                               有效位數(significant digit)的最大數目
%s                                        要打印字符的最大數目

下面是幾個精度的例子:

對於轉換指示符%b,%c與%s而言,相對應的參數都視爲字符串。否則,它們會被解釋爲C語言的數字常數(
以0開頭的爲八進制,以0x或0X開頭的爲十六進制)。更進一步的說,如果參數的第一個字符爲單引號或
雙引號,則相對應的數值是字符串的第二個字符的ASCII值:
發佈了4 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章