ファイルに名前がリストされているファイルをランダムに選択してチェックサムを計算します。

ファイルに名前がリストされているファイルをランダムに選択してチェックサムを計算します。

という名前のファイルがあり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

ファイル内のパスが改行で終了し、そのまま提供されている場合、つまり各行が個別の逐語的パスである場合、シェル ループは次のようになります。

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

またxargs、(POSIX仕様そしてより高度なGNUxargs)、 があるGNUparallel(注記非GNUがparallel存在する(そして、私はそれを指しているのではありません) 適切なツールと適切なオプションを使用すると、1 つのcksumプロセスを複数のパスにしたり (cksum一般的に、プロセスの生成数が少ないほど有利です)、2 つ以上のcksumプロセスを並行して実行したりできます。

3 つのファイルを処理するだけであれば、移植性を考慮してシェル ループを使用するかもしれません。ただし、ファイルが大きく、3 つのcksumプロセスを並行して実行する方が 1 つずつ実行するよりも大幅に高速になると予想される場合は別ですcksum。私は GNU の専門家ではありませんparallelが、解決策は次のように簡単なようです。

 shuf -n 3 list_of_files.txt | parallel cksum

デフォルトでは、GNU はparallelCPU コアの数によって同時ジョブの数を制限します。最近では 3 つ以上のコアが一般的であるため、コマンドはおそらく 3 つのcksumプロセスを並列に実行します。ただし、形式的にはこれは移植性がありません。また、3 つのファイルを並列に処理するということは、3 つのファイルを並列に読み取ることを意味することにも注意してください。I/O がボトルネックになる可能性があり、これにより並列ジョブの利点が減ったり、状況が悪化したりする可能性があります。

それでもparallel役に立つかもしれません。-j 1ジョブの数を 1 に制限するために使用します。

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

ファイルはシェルループと同様に順番に処理されますが、構文はより単純です。シェルループの場合、IFS= read -r pth、だけでなくread pth、(多くのシェルで)あなたが望むことを知っておく必要がありますcksum "$pth"ではなく、ですcksum $pth。GNU を使用したソリューションの方parallelがエラーが発生しにくくなります。キス

xargsデフォルトでは、 は引用符とバックスラッシュを解釈し、スペースを区切り文字と見なすことに注意してください。shuf -n 3 list_of_files.txt | xargs cksumつまり、 はおそらくあなたが望むものではないということです。あなたの例は動作しますが、一般的には、ファイル内に追加の引用符やバックスラッシュが必要です。 xor はGNU の非移植オプションです。私の想定では、「ファイル内のパスは改行で終了し、xargs -d '\n'そのまま提供される」というものでした。この想定では、GNU はそのままで動作します (つまり、追加オプションなしで) が、 xargs は動作しません。GNU では、次のように実行できます。-dxargsparallelxargs

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

GNU を使用できる場合xargs( で困ったときに-d '\n')、おそらく GNU を使用できますparallel。GNU-j 1を使用するときにを忘れるとparallel、コマンドのパフォーマンスは低下する可能性がありますが、それでも動作します。GNU を使用するときに を忘れ、パス名がそのまま提供された場合-d '\n'xargsそれはバグです。そのため、最初に GNU を推奨しましたparallel

GNU parallel はヌル終端文字列 (オプションは-0) を処理できます。GNU xargs(-0の代わりに-d '\n') や GNU shuf( を使用-z) も同様です。入力ファイルでは改行で終了する行が使用されていますが、改行文字を含む (可能性のある) パス名を操作する必要がある場合は、ファイル内の終端文字を変更し、適切なオプションを追加してください。

関連情報