散列多个文件

And*_*NER 3 python bash perl hash batch-processing

问题规范:

给定一个目录,我想遍历目录及其非隐藏的子目录,
 并在非隐藏文件的名称中添加一个漩涡哈希.
如果脚本重新运行,它将用新的哈希替换旧哈希.

<filename>.<extension>   ==>  <filename>.<a-whirlpool-hash>.<extension>

<filename>.<old-hash>.<extension>   ==>  <filename>.<new-hash>.<extension>


题:

a)你会怎么做?

b)在您可用的所有方法中,是什么让您的方法最合适?


判决:

谢谢大家,我选择了SeigeX的答案,因为它具有速度和便携性.
它在经验上比其他bash变种更快,
 并且它在我的Mac OS X机器上没有改变.

Sie*_*geX 6

更新以修复:
1.文件名在其名称中带有'['或']'(实际上,现在是任何字符.请参阅注释)
2 .在名称中使用反斜杠或换行符散列文件时处理md5sum
3.功能化哈希-checking algo for modularity
4.重构哈希检查逻辑以删除双重否定

#!/bin/bash
if (($# != 1)) || ! [[ -d "$1" ]]; then
    echo "Usage: $0 /path/to/directory"
    exit 1
fi

is_hash() {
 md5=${1##*.} # strip prefix
 [[ "$md5" == *[^[:xdigit:]]* || ${#md5} -lt 32 ]] && echo "$1" || echo "${1%.*}"
}

while IFS= read -r -d $'\0' file; do
    read hash junk < <(md5sum "$file")
    basename="${file##*/}"
    dirname="${file%/*}"
    pre_ext="${basename%.*}"
    ext="${basename:${#pre_ext}}"

    # File already hashed?
    pre_ext=$(is_hash "$pre_ext")
    ext=$(is_hash "$ext")

    mv "$file" "${dirname}/${pre_ext}.${hash}${ext}" 2> /dev/null

done < <(find "$1" -path "*/.*" -prune -o \( -type f -print0 \))
Run Code Online (Sandbox Code Playgroud)

到目前为止,此代码与其他条目相比具有以下优点

  • 它完全符合Bash 2.0.2及更高版本
  • 没有多余的调用其他二进制文件,如sed或grep; 使用内置参数扩展代替
  • 使用'find'的进程替换而不是管道,没有这样的子shell
  • 将目录作为参数进行处理并对其进行健全性检查
  • 使用$()而不是``命令替换符号,后者不推荐使用
  • 使用带空格的文件
  • 使用带换行符的文件
  • 适用于具有多个扩展名的文件
  • 使用没有扩展名的文件
  • 不遍历隐藏的目录
  • 难道不是跳过预散列文件,它会重新计算哈希值按规范

测试树

$ tree -a a
a
|-- .hidden_dir
|   `-- foo
|-- b
|   `-- c.d
|       |-- f
|       |-- g.5236b1ab46088005ed3554940390c8a7.ext
|       |-- h.d41d8cd98f00b204e9800998ecf8427e
|       |-- i.ext1.5236b1ab46088005ed3554940390c8a7.ext2
|       `-- j.ext1.ext2
|-- c.ext^Mnewline
|   |-- f
|   `-- g.with[or].ext
`-- f^Jnewline.ext

4 directories, 9 files 

结果

$ tree -a a
a
|-- .hidden_dir
|   `-- foo
|-- b
|   `-- c.d
|       |-- f.d41d8cd98f00b204e9800998ecf8427e
|       |-- g.d41d8cd98f00b204e9800998ecf8427e.ext
|       |-- h.d41d8cd98f00b204e9800998ecf8427e
|       |-- i.ext1.d41d8cd98f00b204e9800998ecf8427e.ext2
|       `-- j.ext1.d41d8cd98f00b204e9800998ecf8427e.ext2
|-- c.ext^Mnewline
|   |-- f.d41d8cd98f00b204e9800998ecf8427e
|   `-- g.with[or].d41d8cd98f00b204e9800998ecf8427e.ext
`-- f^Jnewline.d3b07384d113edec49eaa6238ad5ff00.ext

4 directories, 9 files