仅使用md5sum获取哈希值(不包括文件名)

258

我使用md5sum为文件生成哈希值。 但我只需要接收哈希值,而不是文件名。

md5=`md5sum ${my_iso_file}`
echo ${md5}

输出:

3abb17b66815bc7946cefe727737d295  ./iso/somefile.iso

我如何“剥离”文件名并仅保留其值?


61
很惊讶,md5sum 没有这个选项。 - Sridhar Sarnobat
20
同意!为什么没有这个选项?能否请一位GNU大师解释一下? - rinogo
1
为什么你需要一个“仅哈希”标志,当你可以用一些正则表达式来修剪结果呢?(我是在讽刺) - Magnetic_dud
17个回答

256

简单的数组赋值... 注意,在Bash数组中,可以通过name而无需使用[0]索引来访问第一个元素,即$md5仅包含md5sum的32个字符。

md5=($(md5sum file))
echo $md5
# 53c8fdfcbb60cf8e1a1ee90601cc8fe2

2
第一行在for循环的do部分中不起作用...作为Bash新手,我还不知道为什么。 - Andy
1
@Andy:如果你在终端或脚本中尝试这行代码:echo>文件; for i in 文件; do md5=($(md5sum 文件)); echo $md5; done - 它应该输出 68b329da9893e34099c7d8ad5cb9c940 - Peter.O
1
为什么 echo ($(echo -n foo | md5sum)) 不能正常工作?会出现错误 bash: syntax error near unexpected token $(echo -n foo | md5sum)' - lkraav
3
命令echo -n foo | md5sum会将结果输出到标准输出,包括2个Shell单词:acbd18db4cc2f85cedef654fccc4a4d8-(其中的 -表示源是标准输入)。使用命令替换语法$( command )可以让Bash将这些单词捕获到一个字符串中。使用圆括号( )将数组构建为Bash数组,并且可以通过给数组取一个变量名来进行赋值。例如,使用md5=($(echo -n foo | md5sum))将数组赋值给变量名为md5的数组。你还没有将该数组分配给一个变量名。 - Peter.O
4
这是一个 Bash 问题,但请注意,在 zsh 中不起作用。相反,您可以使用 echo $md5[1] 来仅获取哈希值(但这在 Bash 中不可移植)。 - Shane
显示剩余5条评论

226

使用AWK

md5=`md5sum ${my_iso_file} | awk '{ print $1 }'`

在Mac上,它会输出以下内容:MD5 (/Users/hello.txt) = 24811012be8faa36c8f487bbaaadeb71,而你的代码却只返回了 MD5 - alper
你可以通过在代码结尾添加 | awk '{print $1}' 来获取 - 的运行 => md5sum < ${my_iso_file} | awk '{print $1}' @ChristopheDeTroyer - alper

86
你可以使用cut命令来按空格分割行并仅返回第一个字段:
md5=$(md5sum "$my_iso_file" | cut -d ' ' -f 1)

7
@CzarekTomczak 没错,但是只要使用这个答案的方法,你就可以通过改变命令本身来重复使用不同的哈希算法。 md5sum -> sha256sum,而无需记住需要“剪切”的字符数量。 - David Tabernero M.

32

在Mac OS X上:

md5 -q file

1
无法在我的 Mac OS X 10.7 上运行。但是感谢您的发布,无论这个版本适用于哪个系统。 - Sridhar Sarnobat
此外,coreutils 中的 gmd5sum 也可以在 MacOS 上像其他答案中提到的 md5sum 一样工作。 - Anton Tarasenko
它在版本 11.5.2 上对我有效,但在删除 -q 选项后不再有效。 - Jhoan Manuel Muñoz Serrano
"md5"与"md5sum"是不同的,这也是OP所询问的。 - Cameron Hudson

17
md5="$(md5sum "${my_iso_file}")"
md5="${md5%% *}" # remove the first space and everything after it
echo "${md5}"

不错。有一个注意点——在第一行中,您不需要在 $() 周围加引号(尽管它们没有任何影响),但肯定需要在 ${} 周围加上引号。 - Roman Cheplyaka
2
@Roman:是的,我倾向于习惯性地引用任何扩展(除非有理由不这样做)——这比跟踪可以安全省略引号的情况要容易。 (尽管在这种情况下,我没有在实际文件名上加引号...请等待编辑。) - Gordon Davisson

14

另一种方法是这样做:

md5sum filename | cut -f 1 -d " "

cut 命令将按空格将每行分割并返回第一个字段。


8

通过依靠 head 标签:

md5_for_file=`md5sum ${my_iso_file}|head -c 32`

7
如果您需要打印内容并且不需要换行,您可以使用以下代码:
printf $(md5sum filename)

6

一种方法:

set -- $(md5sum $file)
md5=$1

另一种方法:
md5=$(md5sum $file | while read sum file; do echo $sum; done)

另一种方法:

md5=$(set -- $(md5sum $file); echo $1)

(如果你不是非常勇敢并且擅长反斜杠,请不要尝试使用反引号。)

这些解决方案相对于其他解决方案的优势在于它们只调用md5sum和shell,而不是其他程序,如awksed。但是否真正有影响则是另一个问题;你可能很难注意到差异。


这个问题被标记为Bash,但是也许需要指出其中多少是Bash特定的(例如,在 Z shell 中是否有效(现在据称是macOS v10.15(Catalina)及更高版本的默认shell)。 - Peter Mortensen

3
md5=$(md5sum < $file | tr -d ' -')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接