因为我没有找到直接的方法将文件名提供给pv
(手册页), (除了一个奇怪的-N
开关,它充当前缀,而不是文件名本身),我需要手动编辑文本末尾,该文本sha512sum
或任何其他 shaXsum 通过管道输出,例如:
pv -W "$file" | sha512sum -b
我将它存储在一个变量中sha_output
,但我想给你更纯粹例如,原始代码是:
sha_output=$( pv -W "$file" | sha512sum -b )
哈希总和文本输出示例:
2a19f5852ba8f76bd5a67db18539d609baaf3888b27a57181564db01ef6c16812c60e306973edc059221f61bf2ad9f4b4ef5ff09bbcef98e74a27971c67bdc18 *-
期望的输出:
2a19f5852ba8f76bd5a67db18539d609baaf3888b27a57181564db01ef6c16812c60e306973edc059221f61bf2ad9f4b4ef5ff09bbcef98e74a27971c67bdc18 linuxmint-19.2-cinnamon-64bit.iso
(是的,哈希值和文件名之间有 2 个空格)。
最后,让我们假设文件名存储在名为 的变量中file_name
。
解决方案不得包含任何巴什主义,仅便携式(POSIX)请提供解决方案。
借助这个回答,我整理了以下内容:
printf '%s\n' "${sha_output//\*-/$file_name}"
令人惊讶的是,它在 Bash 下(在某种程度上)有效,但 Dash 出错并显示消息:
bad substitution
由于大括号扩展不是由 POSIX 定义的,根据注释,这并不奇怪。
答案1
假设$file
是您想要替换到校验和输出中的单个文件的名称或路径名。
pv "$file" | sha256sum | { IFS=' ' read sum junk && printf '%s %s\n' "$sum" "$file"; }
管道的最后一部分读取校验和以及sha256sum
第一行的其他输出,然后打印校验和,后跟原始文件名。
请注意,实际上并不需要使用,sha256sum -b
因为这些工具在 Unix 上的二进制文件和文本文件之间没有区别。
答案2
由于您正在捕获变量中已有的命令输出,因此您可以“捕获并更正”变量(POSIXly,yes 在破折号中运行):
sha_output=$( pv -W "$file" | sha512sum -b)
sha_output="${sha_output%\*-} $file"
将${...%\*-}
删除尾随*-
,然后附加一个空格和文件名。实际上,该-b
模式仅在访问文件时区分二进制模式和文本模式的操作系统(即仅限MS-DOS)中有用。因此,-b
不需要任何选项shaXsum
,并且星号 ( *
) (信令二进制模式)将变为空格(信令文本模式)。
如果您不捕获但想要打印输出,您可以使用:
$ printf '%s\n' "$(pv "$file" | sha256sum | sed 's/-$//')$file"
2a19f5852 ... a27971c67bdc18 linuxmint-19.2-cinnamon-64bit.iso
或者@Kusalananda回答。
所有答案都同样有效、POSIX 兼容且有用。
请注意,上述所有内容并不模仿shaXsum
某些文件名(带有换行符或斜杠)将使哈希行以反斜杠开头的确切行为。
如果file='wo\\rds'
(包含反斜杠)输出为:
$ sha256sum "$file"
\f6c94d35691b9c356f7e5072f94d23f127b168cf9b04f0f5b26e0cb1f6ef4414 wo\\rds
请注意,该行以反斜杠开头,并且文件名中的有问题的字符用反斜杠转义。
你的命令不会模仿:
$ printf '%s\n' "$(pv "$file" | sha256sum | sed 's/-$//')$file"
f6c94d35691b9c356f7e5072f94d23f127b168cf9b04f0f5b26e0cb1f6ef4414 wo\rds