如何在 Linux 上使用 Bash printf 命令

已發表: 2022-06-25
藍色背景上的 Linux 終端。
fatmawati achmad zaenuri/Shutterstock.com

Bash printf命令讓您可以通過比echo命令提供的更好的控制和更多的格式選項來寫入 Linux 終端窗口。 甚至printf的怪癖也很有用。

寫入終端

它是與程序交互的最基本部分之一。 程序在屏幕上寫了一些東西,然後你就讀了。 即使考慮到 Unix 派生和 Linux 支持的命令行程序約定盡可能簡潔——許多人只在出現問題時才寫入終端。 告訴用戶正在發生的事情、即將發生的事情或剛剛發生的事情是基本的編程原語。

如何在 Linux 上使用 echo 命令
相關如何在 Linux 上使用 Echo 命令

Bash shell 有echo命令,可以將文本寫入終端窗口。 如果變量包含在字符串中,它可以處理變量並顯示它們的值,您可以在腳本或命令行中使用它。 那麼為什麼printf甚至存在呢? echo沒有覆蓋文字書寫的東西嗎? 好吧, printf提供的功能超越了將字符串寫入終端窗口的普通行為。 它允許您以極大的靈活性格式化輸出,並且它還有其他技巧。

Bash printf命令是仿照 C 語言中的printf函數,但還是有區別的。 如果您了解 C,則需要注意這些差異。

編寫基本字符串

讓我們看看echoprintf在將字符串寫入終端時有何不同。

 echo 這裡有一些話
printf 這裡有一些話

將 echo 和 printf 與未引用的單詞一起使用

echo命令打印所有單詞,但printf只打印第一個單詞。 此外, printf沒有打印新行。 輸出與命令提示符直接對接。 但是,首先要讓printf作用於所有單詞,它們需要被引用。

 echo 這裡有一些話
printf "這裡有幾句話" 

使用帶引號的 echo 和 printf

這樣更好。 我們已經打印了所有的單詞,但我們仍然沒有得到新的一行。 那是因為使用printf時,如果您要求換行,您只會得到一個新行。 這可能看起來很痛苦,但它可以讓您決定是否包含一個。 要使printf發出一個新行,您需要在字符串中包含“ \n ”。 這是“換行符”轉義序列。

 echo 這裡有一些話
printf "這裡有一些單詞\n" 

使用帶引號的單詞和換行符的 echo 和 printf

有時你會使用換行符,有時你不會。 這是一個printf語句使用新行而另一個不使用的情況。

 printf "How-To" && printf "Geek\n" 

使用兩個 printfs 創建單行文本

因為第一個printf不打印新行,所以第二個printf的輸出位於“How-To”之後的同一行。 第二個printf確實使用\n來打印新行。 這使得命令提示符出現在打印文本下方的行上。

相關:如何在 Linux Bash 腳本中逐行處理文件

其他轉義字符

這裡還有一些您可以使用的轉義字符。 您已經看到了“ \n ”的作用。

  • \n :下移到新行。
  • \r :打印回車。 這會將輸出光標發送回當前行的開頭。
  • \t :打印製表符。
  • \v :打印垂直製表符空間。
  • \\ :打印反斜杠字符。
  • \” :打印一個引號字符。
  • \b :打印退格字符。

回車轉義字符將光標移回當前行的開頭。

 printf "蜂蜜是萬惡之源\r金錢\n" 

使用回車符移回行首

printf命令從左到右處理其輸入。 該字符串作為普通文本打印,直到printf遇到“ \r ”轉義字符。 輸出光標移回當前行的開頭。

字符串的處理從緊跟在“ \r ”字符後面的字母開始。 處理餘數會導致printf打印“Money”,覆蓋單詞“Honey”。

引號“ " ”用於引用字符串,反斜杠“ \ ”字符表示轉義序列。如果要打印這些字符,則需要使用反斜杠對其進行轉義。這告訴printf將它們視為文字字符。

 printf "這是一個\tTab,這是一個引號\",這個\\是一個反斜杠\n" 

轉義字符,以便按字面意思對待它們

使用變量

printf中使用變量與在echo中使用它們非常相似。 要包含一個變量,比如這個環境變量,像往常一樣在它前面加上美元符號“ $ ”。

 printf "主目錄:$HOME\n" 

將 printf 與環境變量一起使用

相關:如何在 Bash 中使用變量

格式化字符串

格式字符串是定義輸出格式的字符串。 您提供文本和其他值作為要操作的格式字符串的參數。

格式字符串可以包括文本、轉義序列和格式說明符。 格式說明符告訴printf期望的參數類型,例如字符串、整數或字符。

這些是最常見的格式說明符。 它們都以百分號“ % ”開頭。 要打印百分號,請同時使用兩個百分號“ %% ”。

  • %s : 打印一個字符串。
  • %c :打印單個字符。
  • %d :打印一個整數。
  • %f :打印一個浮點數。
  • %u :打印一個無符號整數。
  • %o :以八進制打印一個值。
  • %x :以小寫形式打印十六進制值。
  • %X :以大寫十六進制打印一個值。
  • %e :以小寫形式以科學計數法打印浮點數。
  • %E :以大寫的科學計數法打印浮點數。
  • %% :打印百分比“%”符號。
 printf "How-To %s\n" "Geek"
 printf "%s%s %s\n" "How" "-To" "Geek" 

顯示 printf 接受“太多”參數

第一個命令中的格式字符串包含一些它自己的文本。 我們將字符串“Geek”作為參數傳遞給printf 。 它與“ %s ”格式說明符匹配並由其打印。 請注意,格式字符串和參數字符串之間只有一個空格。 在 C 語言中,您需要一個逗號來分隔它們,但對於printf的 Bash 版本,使用空格就足夠了。

第二個格式字符串僅包含格式說明符和換行符轉義序列。 三個字符串參數依次被每個“ %s ”格式說明符使用。 同樣,在 C 中,您需要在每個參數之間放置一個逗號,但 Bash printf讓我們忘記了這一點。

要打印不同類型的參數,您只需使用適當的格式說明符。 這是一個使用printf構建的快速數字轉換例程。 我們將以十進制、八進制和十六進製表示法打印值 15。

 printf "Dec: %d\nOct: %o\nHex: %x\n" 15 15 15 

使用 printf 以不同的基本符號打印數值

讓我們稍微修剪一下,以使示例不那麼混亂。

 printf "十六進制: %x\n" 15 

打印十六進制值

我們大多數人習慣於看到大寫的十六進制值,並且小於 0x10 的值打印前導零。 我們可以通過使用大寫十六進制格式說明符“ %X ”並在百分號“ % ”和“ X ”字符之間放置一個寬度說明符來實現這一點。

這告訴printf應該打印參數的字段的寬度。該字段用空格填充。 使用這種格式,將打印兩位數的值而無需任何填充。

 printf "十六進制: %2X\n" 15 

在 2 個字符寬度的字段中以大寫形式打印十六進制值

我們現在得到一個大寫的值,打印有一個前導空格。 我們可以通過在兩者前面放一個零來使printf用零而不是空格填充字段:

 printf "十六進制: %02X\n" 15 

在用零填充的 2 字符寬度字段中以大寫形式打印十六進制值

精度說明符允許您設置要包含在輸出中的小數點數。

 printf "浮點數:%08.3f\n" 9.243546 

使用帶浮點數的寬度和精度修飾符

這使得生成具有整齊對齊輸出的結果表變得容易。 下一個命令還演示了 Bash printf的另一個怪癖。 如果參數多於格式說明符,則將參數分批輸入格式字符串,直到所有參數都用完。 一次處理的批處理大小是格式字符串中格式說明符的數量。 在 C 中, printf函數調用中的額外參數被忽略。

 printf "浮點數:%8.3f\n" 9.243546 23.665 8.0021 

使用寬度和精度修飾符創建一個整潔的表格

您也可以將寬度和精度說明符與字符串一起使用。 此命令在 10 個字符寬的字段中打印字符串。

 printf "%10s %d\n" "外套" 7 "鞋子" 22 "雨傘" 3 

對字符串使用寬度修飾符

默認情況下,值在其字段中是右對齊的。 要使它們左對齊,請在百分號“ % ”符號後面使用減號“ - ”。

 printf "%-10s %d" "外套" 7 "鞋子" 22 "雨傘" 3 

對字符串使用左對齊寬度說明符

精度說明符可用於設置打印的最大字符數。 我們使用冒號“ : ”來顯示寬度字段的限制。 不是“雨傘”這個詞是如何被截斷的。

 printf ":%10.6s:\n" "大衣" "鞋子" "雨傘"
 printf ":%-10.6s:\n" "大衣" "鞋子" "雨傘" 

使用精度修飾符限制從字符串打印的字符數

寬度說明符甚至可以作為參數傳入。 使用星號“ * ”代替數字說明符,並將寬度作為整數參數傳遞。

 printf "%*s\n" 20 "最右邊" 12 "中間" 5 "最左邊" 

將寬度說明符作為參數傳遞給 printf

其他技巧和怪癖

格式字符串中的格式說明符將使用適當類型的值,無論它們是在命令行上作為常規參數提供還是作為表達式的輸出生成。

這將打印兩個數字的總和:

 printf "23+32=%d\n" $((23+32)) 

打印兩個數字的總和

此命令打印當前工作目錄中的目錄數:

 printf "有 %d 個目錄\n" $(ls -d */ | wc -l) 

使用 printf 計算目錄

printf命令打印從調用另一個命令返回的字符串。

 printf "當前用戶: %s\n" $(whoami) 

打印另一個命令的輸出

如果字符串格式說明符“ %s ”沒有提供參數printf什麼也不打印。

 printf "一:%s 二:%s\n" "Alpha" 

printf 如何處理丟失的字符串參數

如果錯誤地為字符串格式說明符“ %s ”提供了數值,它會像字符串一樣打印它並且不會抱怨。 不要用 C printf嘗試這個——會發生非常糟糕的事情。 您的程序可能會崩潰。 但是 Bash printf可以毫無怨言地處理它。

 printf "一:%s 二:%s\n" "Alpha" 777 

printf 如何靜默接受整數作為字符串值

如果整數格式說明符“ %d ”沒有收到任何參數,它將打印零。

 printf "整數:%d\n" 

printf 如何處理丟失的整數參數

如果整數格式說明符“ %d ”錯誤地接收到字符串參數,Bash 將打印一條錯誤消息,而printf將打印零。

 printf "整數: %d\n" "七" 

printf 如何處理提供的字符串而不是整數參數

尷尬的符號可以通過使用它們的 Unicode 數字或“代碼點”來生成。 這些使用字母“u”進行轉義,後跟它們的 Unicode 值。

 printf "歐元符號:\u20AC\n" 

打印轉義的 Unicode 值

要在參數字符串中包含轉義序列,您必須在格式字符串中使用“ %b ”格式說明符,而不是“ %s ”字符串格式說明符。

 printf "%s" "\u20AC\n"
 printf "%b" "\u20AC\n" 

使用 he %b 格式說明符處理字符串參數中的轉義序列

第一個printf語句不處理 Unicode 值,也不識別換行符轉義序列。 第二個printf語句使用“ %b ”格式說明符。 這會正確處理 Unicode 字符並打印新行。

相關:什麼是 ANSI 和 Unicode 等字符編碼,它們有何不同?

課程用馬

有時您需要做的就是將一些文本echo顯到終端窗口。 但是當您需要應用一些定位和格式時, printf是適合該工作的工具。

 printf "%b" "Tha-" "tha-" "tha-" "這就是所有人。\n"