我听说printf比echo. 根据我的经验,我只能回忆起一个我不得不使用的实例,printf因为它echo无法将一些文本输入到 RHEL 5.8 上的某个程序中,但printf确实如此。但显然,还有其他差异,我想询问它们是什么以及是否有特定情况下何时使用一种与另一种。
我正在尝试使用 printf 在 bash 脚本中格式化一些漂亮的输出
例如:
-----------------------
| This is some output |
-----------------------
Run Code Online (Sandbox Code Playgroud)
但我偶然发现了一些我不明白的行为。
$ printf "--"
Run Code Online (Sandbox Code Playgroud)
给我错误:
printf: 用法: printf [-v var] 格式 [参数]
和
$ printf "-stuff"
Run Code Online (Sandbox Code Playgroud)
结果是
-bash: printf: -s: 无效选项
所以显然 printf 认为我试图传递一些参数,而我不是。
同时,完全出于偶然,我找到了这个解决方法:
-----------------------
| This is some output |
-----------------------
Run Code Online (Sandbox Code Playgroud)
给我
--- this works now ----
Run Code Online (Sandbox Code Playgroud)
谁能解释这种行为?
如果我执行以下简单脚本:
#!/bin/bash
printf "%-20s %s\n" "Früchte und Gemüse" "foo"
printf "%-20s %s\n" "Milchprodukte" "bar"
printf "%-20s %s\n" "12345678901234567890" "baz"
Run Code Online (Sandbox Code Playgroud)
它打印:
Früchte und Gemüse foo
Milchprodukte bar
12345678901234567890 baz
Run Code Online (Sandbox Code Playgroud)
也就是说,带有变音符号(例如ü)的文本每个变音符号“缩小”一个字符。
当然,我在某处有一些错误的设置,但我无法弄清楚可能是哪一个。
如果文件的编码为 UTF-8,则会发生这种情况。
如果我将其编码更改为 latin-1,则对齐是正确的,但变音符号呈现错误:
Fr?chte und Gem?se foo
Milchprodukte bar
12345678901234567890 baz
Run Code Online (Sandbox Code Playgroud) MYPATH=/var/www/html/error_logs/
TOTALFILE=$(ls $MYPATH* | wc -l)
FILETIME=$(stat --format=%y $MYPATH* | head -5 | cut -d'.' -f1)
FILE=$(ls -1tcr $MYPATH* | head -5 | rev | cut -d/ -f1 | rev)
TOPLINE=$(head -1 $MYPATH* | grep -Po '".*?"' | head -5)
Run Code Online (Sandbox Code Playgroud)
我如何优雅地将这 5 个文件信息打印到带有标题的列中?
FILE CREATED TIME | FILE NAME | ERROR HEADER
---------------------------------------------
$FILETIME | $FILE | $TOPLINE
2012-11-29 11:27:45 | 684939947465 | "SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)"
Run Code Online (Sandbox Code Playgroud)
等等 5个文件
total files: $TOTALFILE …
我需要打印出一个数字,但具有给定的宽度和四舍五入(使用 awk!)
%10s
Run Code Online (Sandbox Code Playgroud)
我有这个,但不知何故我需要连接,%d但我所做的一切,最终都会有太多的 awk 参数(因为我有更多的列)。
我想用来printf打印一个变量。此变量可能包含%百分号。
最小的例子:
$ TEST="contains % percent"
$ echo "${TEST}"
contains % percent
$ printf "${TEST}\n"
bash: printf: `p': invalid format character
contains $
Run Code Online (Sandbox Code Playgroud)
(echo提供所需的输出。)
我正在使用 Adobe Source Code Pro 字体通过简单终端运行 Arch Linux。我的语言环境正确设置为LANG=en_US.UTF-8.
我想将代表扑克牌的 Unicode 字符打印到我的终端。我正在使用维基百科作为参考。
卡片套装的 Unicode 字符工作正常。例如,发行
$ printf "\u2660"
Run Code Online (Sandbox Code Playgroud)
在屏幕上打印一个黑色的心。
但是,我在使用特定的扑克牌时遇到了问题。发行
$ printf "\u1F0A1"
Run Code Online (Sandbox Code Playgroud)
打印符号?1而不是黑桃 A。怎么了?
这个问题在多个终端(urxvt、xterm、termite)和我尝试过的每种字体(DejaVu、Inconsolata)中仍然存在。
该yash外壳有一个printf内置的,根据其说明书。
但是,这是我在yash具有默认配置的shell 中看到的:
$ command -v printf
/usr/bin/printf
$ type printf
printf: a regular built-in at /usr/bin/printf
Run Code Online (Sandbox Code Playgroud)
printf这个shell中是否内置了?结果与许多其他假定的内置实用程序类似,这些实用程序也可用作外部命令。
作为对比,在pdksh(ksh在OpenBSD,这里printf是不是内置的):
$ command -v printf
/usr/bin/printf
$ type printf
printf is /usr/bin/printf
Run Code Online (Sandbox Code Playgroud)
并在bash(其中printf 是内置的):
$ command -v printf
printf
$ type printf
printf is a shell builtin
Run Code Online (Sandbox Code Playgroud) 格式良好的printf通常有一个可以使用的格式:
$ var="Hello"
$ printf '%s\n' "$var"
Hello
Run Code Online (Sandbox Code Playgroud)
但是,不提供格式可能会产生什么安全隐患?
$ printf "$var"
Hello
Run Code Online (Sandbox Code Playgroud)
由于变量扩展被引用,应该不会有任何问题,不是吗?
我发现以下命令可以在 Linux 中重复一个字符:
printf 'H%.0s' {1..5000} > H.txt
Run Code Online (Sandbox Code Playgroud)
例如,我想H重复5000时间。%.0s这里是什么意思?