Linux常用命令--echo与printf

摘要

  • 在编写 shell 脚本时,echo 和 printf 是两个常用的命令,用于输出信息到标准输出设备。虽然它们看似简单,但深入理解它们的使用方式和内部机制对于编写高效、可读性强的脚本至关重要。

echo 命令

基本语法和用法

  • echo 命令的基本语法为:

1
echo [选项] [字符串或变量]
  • 参数和选项

1
2
3
4
5
-n:不换行输出。
-e:解释转义字符。
-E:禁止解释转义字符。

常见的转义字符包括 \n(换行)、\t(制表符)等。

实际应用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 打印一个文本消息。注意:引号是可选的
echo "Hello World"

- 打印一个带环境变量的消息
echo "My path is $PATH"

- 打印一个不带尾随换行符的消息
echo -n "Hello World"

- 将消息追加到文件中
echo "Hello World" >> file.txt

- 启用反斜杠转义(特殊字符)的解释
echo -e "Column 1\tColumn 2"

- 打印最后一个执行命令的退出状态
echo $?

echo输出颜色化文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
echo -e "\e[1;31mError:\e[0m Something went wrong."
# 或
echo -e "\033[1;31mError:\033[0m Something went wrong."

# 说明:
\e[1;31m:这部分控制文本的颜色和样式。
其中:
\e 表示这是一个转义字符,它是 ANSI 转义序列的起始,后跟一系列用于控制文本颜色、样式等的数字和字符。这里\e也可以用\033替代。
1 表示设置文本为粗体(或者称为高亮)。
31 表示设置文本颜色为红色。不同的数字代表不同的颜色,这里的 31 对应红色。

\e[0m:这部分重置文本格式为默认值。这样做是为了确保在之后的输出中文本样式不受之前的影响。

因此,这条命令会输出一个红色的“Error:”,接着是一个空格,然后是普通文本“Something went wrong.”。整体效果是,错误消息以红色高亮显示,使其在输出中更加醒目。


颜色:
30:黑色
31:红色
32:绿色
33:黄色
34:蓝色
35:紫色
36:青色
37:白色

样式:
0:重置所有样式(默认值)
1:粗体(或高亮)
2:暗色(不常见,视终端而定)
3:斜体(不常见,视终端而定)
4:下划线
5:闪烁(不常见,视终端而定)
7:反显(前景色与背景色交换)
8:隐藏(文本不可见)

这些数字和字符可以单独使用,比如\e[1m 表示加粗,\e[31m 表示设置文本颜色为红色。
也可以组合使用,比如 \e[1;31m 表示设置文本为红色并加粗,中间用分号隔开。

printf 命令

基本语法和用法

  • printf 命令的基本语法为:

1
printf [格式化字符串] [参数]

实际应用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 打印文本消息:
printf "%s\n" "Hello world"

- 以蓝色粗体打印整数:使用方法同echo
printf "\e[1;34m%.3d\e[0m\n" 42

- 打印带有Unicode Euro符号的浮点数:
printf "\u20AC %.2f\n" 123.4

- 打印由变量组成的文本消息:
printf "var1: %s\tvar2: %s\n" "$var1" "$var2"

- 将格式化的消息存储在变量中:
printf -v myvar "This is %s = %d\n" "a year" 2016
echo $myvar
This is a year = 2016

在 printf 命令中,支持的格式化符号用于指定输出的格式,包括整数、浮点数、字符串等。
以下是常用的格式化符号及其使用示例:

  • 1.整数格式化符号:

    • %d:以十进制形式输出整数。
    • %.nd:指定数字占几位,不足部分前面补0。
    • %o:以八进制形式输出整数。
    • %x 或 %X:以十六进制形式输出整数(小写或大写)。
    1
    2
    3
    4
    5
    printf "%d\n" 42      # 输出:42
    printf "%.3d\n" 42 # 输出:042
    printf "%o\n" 42 # 输出:52
    printf "%x\n" 42 # 输出:2a
    printf "%X\n" 42 # 输出:2A
  • 2.浮点数格式化符号:

    • %f:以十进制形式输出浮点数。
    • %.nf:指定小数点后保留 n 位小数。
    1
    2
    printf "%f\n" 3.14159      # 输出:3.141590
    printf "%.2f\n" 3.14159 # 输出:3.14
  • 3.字符串格式化符号:

    • %c:输出单个字符。
    • %s:输出字符串。
    1
    2
    printf "%c\n" 'A'      # 输出:A
    printf "%s\n" "Hello" # 输出:Hello
  • 4.其他格式化符号:

    • %p:以十六进制形式输出指针地址。
    • %u:输出无符号整数。
    • %e 或 %E:以科学计数法形式输出浮点数(小写或大写)。
    • %g 或 %G:根据实际情况自动选择 %f 或 %e 格式输出浮点数(小写或大写)。
    • %%:输出一个百分号。
    1
    2
    3
    4
    5
    6
    7
    printf "%p\n" $var           # 输出:0x7ffeefbff748 (变量 var 的地址)
    printf "%u\n" -42 # 输出:4294967254
    printf "%e\n" 123.456 # 输出:1.234560e+02
    printf "%E\n" 123.456 # 输出:1.234560E+02
    printf "%g\n" 123.456 # 输出:123.456
    printf "%G\n" 123.456 # 输出:123.456
    printf "100%%\n" # 输出:100%

不同进制之间进行相互转换

10进制转其它进制

1
2
3
4
5
6
7
8
9
10
11
12
# 10进制转2进制,obase=2 指定输出进制为二进制,默认为10进制。
echo "obase=2; 255" | bc # 11111111
# printf不支持到二进制的转换

# 10进制转8进制
echo "obase=8; 255" | bc # 377
printf "%o\n" 255 # 377,%o 表示八进制数

# 10进制转16进制
echo "obase=16; 255" | bc # FF
printf "%x\n" "255" # ff,%x 表示十六进制数,小写
printf "%X\n" "255" # FF,%X 表示十六进制数,大写

2进制转其它进制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 2进制转10进制,ibase=2 指定输入进制为二进制,默认为10进制。
echo "ibase=2; 11111111" | bc # 255
echo $((2#11111111)) # 255,内置的算术运算 $((...)),可以实现其它进制转10进制
printf "%d\n" "0b11111111" # 255,%d 表示十进制数,对于二进制数,你需要在数字前面加上 0b 的前缀
printf "%d\n" $((2#11111111)) # 255

# 2进制转16进制,两个同时出现时要先声明obase,再声明ibase,否则输出结果错误
echo "obase=16; ibase=2; 11111111" | bc # FF
printf "%X\n" "0b11111111" # FF
printf "%x\n" "0b11111111" # ff
printf "%X\n" $((2#11111111)) # FF
printf "%x\n" $((2#11111111)) # ff

# 2进制转8进制
echo "obase=8; ibase=2; 11111111" | bc # 377
printf "%o\n" "0b11111111" # 377
printf "%o\n" $((2#11111111)) # 377

8进制转其它进制

1
2
3
4
5
6
7
8
9
10
11
12
13
# 8进制转10进制
echo "ibase=8; 377" | bc # 255
echo $((8#377)) # 255
printf "%d\n" $((8#377)) # 255

# 8进制转2进制
echo "obase=2; ibase=8; 377" | bc # 11111111
# printf不支持到二进制的转换

# 8进制转16进制
echo "obase=16; ibase=8; 377" | bc # FF
printf "%X\n" "$((8#377))" # FF
printf "%x\n" "$((8#377))" # ff

16进制转其它进制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 16进制转10进制
echo "ibase=16; FF" | bc # 255
echo $((16#FF)) # 255
printf "%d\n" "0xFF" # 255,%d 表示十进制数,对于十六进制数,你需要在数字前面加上 0x 的前缀
printf "%d\n" $((16#FF)) # 255

# 16进制转2进制
echo "obase=2; ibase=16; FF" | bc # 11111111
# printf不支持到二进制的转换

# 16进制转8进制
echo "obase=8; ibase=16; FF" | bc # 377
printf "%o\n" "0xFF" # 377
printf "%o\n" "$((16#FF))" # 377

echo 与 printf 的比较

输出效果的比较

  • echo 会自动换行,而 printf 需要显式指定换行符。

  • printf 提供更灵活的格式化输出方式。

性能比较

  • 在大量输出时,echo 通常比 printf 更高效。

适用场景的选择

  • 简单文本输出场景,使用 echo。

  • 需要格式化输出或者更精确控制输出格式时,使用 printf。