С GNU sortи printfвстроенной оболочкой (в настоящее время все POSIX-подобные, кроме некоторых вариантов pdksh):
printf '%s\0' * | sort -u --files0-from=- > output
Теперь проблема в том, что, поскольку два компонента этого конвейера запускаются одновременно и независимо, к тому времени, когда левый расширяет *глобус, правый может уже создать outputфайл, который может вызвать проблемы (возможно, не -uздесь) Как outputи входной, и выходной файл, вы можете захотеть, чтобы выходные данные перешли в другой каталог ( > ../outputнапример), или убедитесь, что глобус не соответствует выходному файлу.
Другой способ решения этой проблемы в этом случае - написать:
printf '%s\0' * | sort -u --files0-from=- -o output
Таким образом, он sortоткрывается outputдля записи и (в моих тестах) не будет делать этого, пока не получит полный список файлов (так долго после того, как глобус будет расширен). Это также позволит избежать дублирования, outputесли ни один из входных файлов не будет читаемым.
Другой способ написать это с помощью zshилиbash
sort -u --files0-from=<(printf '%s\0' *) -o output
При этом используется подстановка процесса (где <(...)заменяется путь к файлу, который относится к концу чтения канала, в который printfпроизводится запись). Эта функция взята ksh, но kshтребует расширения <(...)отдельного аргумента для команды, чтобы вы не могли использовать его с --option=<(...)синтаксисом. Это будет работать с этим синтаксисом, хотя:
sort -u --files0-from <(printf '%s\0' *) -o output
Обратите внимание, что вы увидите отличие от подходов, которые catпередают вывод файлов, в тех случаях, когда есть файлы, которые не заканчиваются символом новой строки:
$ printf a > a
$ printf b > b
$ printf '%s\0' a b | sort -u --files0-from=-
a
b
$ printf '%s\0' a b | xargs -r0 cat | sort -u
ab
Также обратите внимание, что sortсортирует, используя алгоритм сортировки в locale ( strcollate()), и sort -uсообщает одну из каждого набора строк, которые сортируются по этому алгоритму, а не уникальные строки на уровне байтов. Если вы заботитесь только об уникальности строк на уровне байтов и не заботитесь о порядке их сортировки, возможно, вы захотите зафиксировать локаль в C, где сортировка основана на значениях байтов ( memcmp(); это, вероятно, ускорит дела обстоят значительно):
printf '%s\0' * | LC_ALL=C sort -u --files0-from=- -o output
sortделает это автоматически для ввода нескольких файлов ... но тогдаsort -u *,Argument list too longя полагаю, тоже потерпел бы неудачу