Переносимый подход, который также обрабатывает странные имена файлов (например, с новой строкой в нем), точечные файлы (имя файла начинается с .
) и другие специальные символы, такие как кавычки (только текущий каталог):
find -maxdepth 1 -type f -iname "*.txt" -print0 | tr -cd '\0' | wc -c
Или рекурсивно (без -maxdepth
), файлы также будут подсчитаны в подкаталогах:
find -type f -iname "*.txt" -print0 | tr -cd '\0' | wc -c
Объяснение:
-maxdepth 1
искать внутри текущего каталога, не переходить в подкаталоги. -тип f
поиск только в обычных файлах. -iname "* .txt"
поиск файлов с окончанием txt без учета регистра. -print0
это важная часть, ограничить список символом нулевого байта tr -cd '\ 0'
удаляет все, кроме символа нулевого байта. wc -c
подсчитывает количество символов (теперь это количество файлов) GNU sort
имеет флаг --parallel
:
sort --parallel=8 data.tsv | uniq -c | sort --parallel=8 -n
Это потребует восьми параллельных процессов/потоков для выполнения каждого из двух шагов сортировки. Часть uniq -c
по-прежнему будет использовать один процесс.
Как отмечает в комментариях Стефан Шазеля, реализация GNU sort
уже распараллелена, (она использует потоки POSIX ), поэтому изменение количества параллельных потоков необходимо только в том случае, если вы хотите использовать больше или меньше потоков, чем у вас есть ядер.
Обратите внимание, что второй sort
, вероятно, получит намного меньше данных, чем первый, из-за шага uniq
, поэтому он будет намного быстрее.
Вы также можете (возможно )повысить скорость сортировки, поэкспериментировав с --buffer-size=SIZE
и --batch-size=NMERGE
. См. руководство sort
.
Чтобы еще больше ускорить сортировку, убедитесь, что sort
записывает свои временные файлы в быструю файловую систему (, если у вас подключено несколько типов хранилища ). Вы можете сделать это, установив переменную окружения TMPDIR
на путь доступного для записи каталога в такой точке монтирования (или используяsort -T directory
).
Это быстрее для меня. YMMV (это определенно зависит от количества дубликатов):
parallel --lb --pipepart --block 15m -a /tmp/big.file 'sort | uniq -c' |
awk '{ count[$2] += $1 } END { for(elem in count) print count[elem], elem }' |
sort -n