hek2mgl's answer хорошо объясняет проблему, и его решение хорошо работает; этот ответ выглядит как производительность.
Принимаемый ответ медленный, потому что он создает процесс bash
для каждой строки ввода.
В то время как xargs
, как правило, предпочтительнее и быстрее, чем цикл оболочки-кода, в данном конкретном случае роли меняются, так как функциональные возможности оболочки необходимо в каждой итерации.
Следующее альтернативное решение использует while
цикла для обработки входных линий, а также, на моей машине, составляет около в два раза быстрее в качестве xargs
раствора.
find . -printf "%P\n" | sort | while IFS= read -r f; do echo "$(uuid) $f"; done
- Обратите внимание на использование
while
, а не for
, потому что for
не может решительно разобрать вывод команды (короче говоря: имена файлов со встроенным пробельных разорвет команду - см http://mywiki.wooledge.org/DontReadLinesWithFor).
Если вы беспокоитесь о именах файлов с вложенными символами новой строки (очень редко) и использовать GNU утилиты, вы можете использовать NUL байт в качестве разделителей:
find . -printf "%P\0" | sort -z | while IFS= read -d '' -r f; do echo "$(uuid) $f"; done
Update: самый быстрый подход не должен использовать петлю оболочки вообще, о чем свидетельствует ᴳᵁᴵᴰᴼ's clever answer. См. Ниже портативную версию его ответа.
примечание Совместимость:
find
Командование OP подразумевает использование GNUfind
(Linux), и использует функции (-printf
), которые не могут работать на других платформах.
Вот портативная версия ᴳᵁᴵᴰᴼ's answer, который использует только POSIX-совместимые функции find
(и awk
).
Обратите внимание, что uuid
не является утилитой POSIX; так как Linux и BSD-подобные системы (включая OSX) имеют uuidgen
полезность, команда использует, что вместо того, чтобы:
find . -exec printf '%s\t' {} \; -exec uuidgen \; |
awk -F '\t' '{ sub(/.+\//,"", $1); print $2, $1 }' | sort -k2
@TomFenech: '-n 1' фактически расколот любой пробел, будь то линейный интерьер или нет, поэтому команда будет разбиваться на пути со встроенным пробелом; '-L 1' приближается к намерению, поскольку он выполняет линейную обработку, но разделение слов по-прежнему применяется к каждой строке, так что потенциально _multiple_ аргументы передаются в' echo' на строку ввода (что может или может не вызывать проблем). Надежный подход заключается в использовании '-I', как в принятом ответе. – mklement0