Вычислить контрольные суммы для случайного набора файлов, имена которых перечислены в файле

Вычислить контрольные суммы для случайного набора файлов, имена которых перечислены в файле

Допустим, у меня есть файл 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и более продвинутыеГНУxargs), естьГНУparallel(примечаниеparallelсуществует не-GNUи я не имею в виду это). С правильным инструментом и соответствующими параметрами вы можете сделать так, чтобы один cksumпроцесс выполнялся на нескольких путях ( cksumв целом, создание меньшего количества процессов выгодно) или запустить два или более cksumпроцессов параллельно.

Чтобы обработать всего три файла, я могу придерживаться нашего цикла оболочки из-за переносимости; если только файлы не большие и я не ожидаю, что три cksumпроцесса, запущенных параллельно, будут значительно быстрее, чем один cksumза раз. Я не эксперт в GNU parallel, но, кажется, решение такое же простое, как:

 shuf -n 3 list_of_files.txt | parallel cksum

По умолчанию GNU parallelограничивает количество одновременных заданий числом ядер ЦП. В настоящее время распространены три или более ядер, поэтому команда, вероятно, запустит три cksumпроцесса параллельно. Формально это непереносимо. Также обратите внимание, что параллельная обработка трех файлов означает параллельное чтение трех файлов. Ввод-вывод может быть узким местом, и это может снизить преимущество параллельных заданий или даже ухудшить ситуацию.

Даже тогда это 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 вам нужен xargs -d '\n'where -d— непереносимая опция GNU xargs. Я предполагал, что «пути в файле завершаются символом новой строки и предоставляются как есть». С этим предположением GNU parallelработает «из коробки» (т. е. без дополнительных опций), xargs — нет. С GNU xargsвы можете сделать это:

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и пути будут предоставлены как есть, то это ошибка. Вот почему я рекомендовал GNU parallelв первую очередь.

GNU parallel способен обрабатывать строки с нулевым завершением (опция -0), как и GNU xargs( -0вместо -d '\n') и GNU shuf-z). Ваш входной файл использует строки с символом новой строки, но если вам когда-либо понадобится работать с путями, которые (могут) содержать символы новой строки, то изменение символа завершения в файле и добавление соответствующих параметров — это выход.

Связанный контент