POSIX-ly 替换尾随文本

POSIX-ly 替换尾随文本

因为我没有找到直接的方法将文件名提供给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

相关内容