という名前のファイルがあり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 はparallel
CPU コアの数によって同時ジョブの数を制限します。最近では 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 では、次のように実行できます。-d
xargs
parallel
xargs
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
) も同様です。入力ファイルでは改行で終了する行が使用されていますが、改行文字を含む (可能性のある) パス名を操作する必要がある場合は、ファイル内の終端文字を変更し、適切なオプションを追加してください。