find ./ | grep " "
получит файлы и каталоги, содержащие пробелы
find ./ -type f | grep " "
получите файлы, содержащие пробелы
find ./ -type d | grep " "
получите каталоги, содержащие пробелы
Как написано на странице руководства и в стандарте, {}
должен быть в отдельном аргументе.
find / -exec sh -c 'echo $ 1' dummy '{}' \;
работает должным образом.
Обратите внимание, что параметр фиктивный
необходим, поскольку оболочка назначает первый аргумент после аргумента команды для sh -c cmd
, чтобы он стал $ 0
, а следующий параметр становится $ 1
.
Единственный стандартный способ использовать find -exec ...
- это передать {}
в качестве отдельного аргумента. Поведение, когда аргумент содержит {}
, не стандартизировано. Похоже, что вы привыкли к поведению GNU, где {}
подставляется в подстроку. Команда find
в Solaris подставляет {}
, только когда аргумент состоит только из {}
.
Поведение GNU не особенно полезно, а иногда и раздражает, потому что замена имени файла внутри аргумента хрупка. Если у вас нет известных ограничений на имена файлов, нет способа узнать, где начинается и где заканчивается имя файла. Например, с помощью GNU find, find / -exec sh -c "echo {}" \;
делает не печать имен файлов вообще. Он печатает имена файлов, только если они не содержат специальных символов оболочки. Если вы запустите его в каталоге, содержащем файл с именем ;rm -r ~
, попрощайтесь со своими файлами.
Надежный (и портативный) способ вызова оболочки из find -exec
- это передача имен файлов в качестве аргумента оболочке.
find … -exec sh -c 'echo "$0"' {} \;
В большинстве случаев вы можете передавать аргументы пачками и перебирать их в оболочке. Это несколько быстрее. Обратите внимание, что самым первым аргументом после кода shell является $0
, который не входит в "$@"
.
find … -exec sh -c 'for x; do echo "$x"; done' _ {} +
См. также Почему мой shell-скрипт подавляется пробелами или другими специальными символами?