Bash 中 echo 和 printf 的区别

Difference between echo and printf in Bash

我正在读取文件的行,将每一行转换为 md5 哈希,然后将其写入第二个文件。根据使用 printfecho.

,我得到了不同的结果
printf $line | md5sum | awk '{print }' >> md5File.txt

echo $line | md5sum | awk '{print }' >> md5File.txt

对于 printf 00000 变为 dcddb75469b4b4875094e14561e573d8,但对于 echo 00000 变为 81b4e43a7bcd862f3ac58b5f8568a668.

我验证了 00000 的正确 md5 哈希和是 dcddb75469b4b4875094e14561e573d8 但我不明白为什么?

使用 echo $line 会自动包含一个换行符 - 您可以使用 -n 选项取消换行(有时 - 见下文)。所以这不起作用:

echo $line | md5sum | awk '{print }' >> md5File.txt

但是在 bash 上是这样的:

echo -n $line | md5sum | awk '{print }' >> md5File.txt

但并非所有 echo 版本都有 -n 选项。 echo documentation 表示:

If the first operand is -n, or if any of the operands contain a backslash ( '\' ) character, the results are implementation-defined. ... On XSI-conformant systems, if the first operand is -n, it shall be treated as a string, not an option.

另一种方法是使用 bash 的 printf 命令。 printf documentation 表示:

The printf utility was added to provide functionality that has historically been provided by echo. However, due to irreconcilable differences in the various versions of echo extant, ...

所以 printf 是可靠的便携方式。这是一个包含更多详细信息的相关答案:https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo

但是如果您不指定格式字符串,使用 printf 是危险的,所以即使这似乎可行:

printf $line | md5sum | awk '{print }' >> md5File.txt

$line 包含百分号或反斜杠时,它将失败。 printf 的第一个参数是格式字符串并被特殊对待。如果格式字符串无效,则 printf 会向 stderr 产生一个错误,并向 stdout 产生一个空字符串,从而给出错误的答案。所以你需要:

printf "%s" "$line" | md5sum | awk '{print }' >> md5File.txt

%s 告诉 printf 期待更多的字符串参数(恰好是 $line)并且您得到正确的输出。

有趣的事实:如果您确实希望 printf 添加尾随换行符(在这种情况下您不需要),那么您会

printf "%s\n" "$line" | md5sum | awk '{print }' >> md5File.txt