bash - Bash 中 echo 和 printf 的区别
问题描述
我正在读取文件的行,将每一行转换为 md5 哈希,然后将其写入第二个文件。printf
基于使用和 ,我得到了不同的结果echo
。
printf $line | md5sum | awk '{print $1}' >> md5File.txt
echo $line | md5sum | awk '{print $1}' >> md5File.txt
对于printf
00000 变为dcddb75469b4b4875094e14561e573d8
,但对于 echo 00000 变为81b4e43a7bcd862f3ac58b5f8568a668
。
我验证了 00000 的正确 md5 哈希和是,dcddb75469b4b4875094e14561e573d8
但我对为什么感到困惑?
解决方案
自动使用echo $line
包含换行符 - 您可以使用-n
选项抑制它(有时 - 见下文)。所以这不起作用:
echo $line | md5sum | awk '{print $1}' >> md5File.txt
但是在 bash 上这样做:
echo -n $line | md5sum | awk '{print $1}' >> md5File.txt
但并非所有版本echo
都有-n
选项。回声文档说:
如果第一个操作数是 -n,或者任何操作数包含反斜杠 ('\') 字符,则结果是实现定义的。...在符合 XSI 的系统上,如果第一个操作数是 -n,则应将其视为字符串,而不是选项。
另一种选择是使用 bash 的printf
命令。printf 文档说:
添加了 printf 实用程序以提供过去由 echo 提供的功能。但是,由于各种版本的 echo extant 存在不可调和的差异,...
printf
可靠的便携方式也是如此。这是一个包含更多详细信息的相关答案: https ://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo
但是printf
如果你不指定格式字符串,那么使用是危险的,所以即使这似乎有效:
printf $line | md5sum | awk '{print $1}' >> md5File.txt
$line
当包含百分号或反斜杠时,它将失败。的第一个参数printf
是格式字符串,并被特殊处理。如果格式字符串无效,则printf
对 stderr 产生错误,对 stdout 产生空字符串,从而给出错误答案。因此,您需要:
printf "%s" "$line" | md5sum | awk '{print $1}' >> md5File.txt
%s
告诉期望再有printf
一个字符串参数(恰好是$line
)并且您得到正确的输出。
有趣的事实:如果您确实想printf
添加尾随换行符(在这种情况下您不需要),那么您会
printf "%s\n" "$line" | md5sum | awk '{print $1}' >> md5File.txt
推荐阅读
- c++ - boost::enable_if 在成员函数上,重载返回类型
- python - 组合多个数据框列
- makefile - patsubst 返回名称后展开变量
- angular - 使用角度路由参数而不订阅它
- umbraco7 - 在 Umbraco 7.6 中无法显示自定义部分
- c# - 我的 .Net Core 应用程序如何使用来自另一个应用程序的会话变量?
- flutter - Flutter TextField清除按钮位置错误
- apache-flink - 将 uid 添加到操作员会导致“无法映射操作员的检查点/保存点状态”
- android - Firebase 函数在 10 秒后在客户端提供超时
- javascript - 您如何定位和修改 Ionic/Angular 应用程序中的所有 CSS 元素实例?