計算文件中列出的隨機選擇的文件的校驗和

計算文件中列出的隨機選擇的文件的校驗和

假設我有一個名為的文件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;你需要知道你(在許多外殼中)想要cksum "$pth", 不是cksum $pth。使用 GNU 的解決方案parallel不太容易出錯。

Note預設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 並行能夠處理以 null 結尾的字串(選項是),GNU (而不是)和 GNU (帶有)-0也是如此。您的輸入檔使用換行符終止的行,但如果您需要使用(可能)包含換行符的路徑名,那麼更改檔案中的終止符並添加正確的選項是可行的方法。xargs-0-d '\n'shuf-z

相關內容