计算文件中列出的随机文件的校验和

计算文件中列出的随机文件的校验和

假设我有一个名为的文件list_of_files.txt,其中每一行对应磁盘上的一个文件。例如:

dir1/fileA.ext1
dir1/subdir1/fileB.ext2
fileC.ext3
dir2/fileD.ext4
fileE.ext5

我想从该列表中随机选择一些文件并计算cksum它们md5sum

我知道我可以用 随机选择 3 个文件shuf -n 3 list_of_files.txt,但是我如何将cksum它们视为文件名而不是文本内容?

答案1

如果文件中的路径以换行符终止并按原样提供,即,如果每行都是单独的逐字路径,则 shell 循环将执行:

shuf -n 3 list_of_files.txt | while IFS= read -r pth; do
   cksum "$pth"
done

还有xargs(见POSIX 规范以及更先进的GNUxargs), 有GNUparallel(笔记非 GNUparallel存在我不是在说这个。使用正确的工具和适当的选项,你可以让一个cksum进程有多个路径(cksum一般来说,生成较少的进程是有益的)或者cksum并行运行两个或多个进程。

为了处理最少三个文件,我可能会坚持使用我们的 shell 循环,因为这样更易于移植;除非文件很大,并且我预计三个cksum进程并行运行的速度会比一次运行一个进程快得多cksum。我不是 GNU 专家parallel,但似乎解决方案很简单:

 shuf -n 3 list_of_files.txt | parallel cksum

默认情况下,GNUparallel会根据 CPU 核心数来限制同时执行的作业数。如今,三核或更多核已很常见,因此该命令可能会cksum并行运行三个进程。不过,从形式上讲,这是不可移植的。还请注意,并行处理三个文件意味着并行读取三个文件。I/O 可能是一个瓶颈,这可能会降低并行作业的好处,甚至使情况变得更糟。

即使这样也parallel可能有用。使用-j 1将作业数量限制为 1:

 shuf -n 3 list_of_files.txt | parallel -j 1 cksum

这些文件将像我们的 shell 循环一样按顺序处理,但语法更简单。在我们的 shell 循环中,你需要知道你想要IFS= read -r pth,而不仅仅是read pth;你需要知道你(在许多 shell 中)想要cksum "$pth",而不是cksum $pth。使用 GNU 的解决方案parallel不太容易出错。

注意xargs默认情况下会解释引号和反斜杠,并将空格视为分隔符。这意味着shuf -n 3 list_of_files.txt | xargs cksum可能不是您想要的。您的示例可以工作,但通常您需要在文件中添加额外的引号和/或反斜杠;xor 您需要xargs -d '\n'where-d是 GNU 的不可移植选项xargs。我的假设是“文件中的路径以换行符结尾并按原样提供”。在这个假设下,GNUparallel开箱即用(即没有附加选项),xargs 则不行。使用 GNUxargs您可以执行以下操作:

shuf -n 3 list_of_files.txt | xargs -d '\n' cksum

如果您可以使用 GNU xargs(为了节省时间-d '\n'),那么您可能可以使用 GNU parallel。如果您忘记了-j 1何时使用 GNU parallel,命令的性能可能会更差,但它仍然可以工作。如果您忘记了-d '\n'何时使用 GNU xargs,并且路径名按原样提供,那么这是一个错误。这就是我parallel首先推荐 GNU 的原因。

GNU parallel 能够处理以空字符结尾的字符串(选项为-0),GNU xargs-0而不是-d '\n')和 GNU shuf(带-z)也能够处理以空字符结尾的字符串。您的输入文件使用以换行符结尾的行,但如果您需要使用(可能)包含换行符的路径名,那么更改文件中的终止符并添加适当的选项是可行的方法。

相关内容