如何在 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"