Во-первых, всегда используйте {}
в качестве отдельного аргумента в find -exec…
. Использование stuff {} morestuff
работает с некоторыми (не всеми) версиями find
, но не может справиться с именами файлов, содержащими «необычные» символы, такие как пробелы, '
, "
и т. Д. (Какие именно символы вызывают проблемы, зависит от того, где именно вы используете {}
). Передайте {}
как отдельный аргумент.Первый аргумент после sh -c CODE
равен $ 0
. Не забывайте двойные кавычки вокруг расширения переменных .
find … -exec sh -c 'ln -s /some/other/path/$(basename "$0") "$0"' {} \;
(Я также упростил цитирование, чтобы использовать одинарные кавычки.)
Есть как минимум еще одна проблема с вашей командой. Вы пытаетесь создать символическую ссылку в месте, возвращаемом find
, где по конструкции уже существует символическая ссылка. Похоже, вы намеревались создать символическую ссылку в / some / other / path
, и в этом случае вам нужно поменять аргументы на ln
(например, с mv
] и cp
, существующие файлы идут первым, а место назначения - последним).
find /some/path/* -maxdepth 0 -exec sh -c 'ln -s "$0" /some/other/path/$(basename "$0")' {} \;
Вы можете сделать это быстрее, используя конструкции управления строкой оболочки вместо basename
и вызывая sh
по частям.
find /some/path/* -maxdepth 0 -exec sh -c '
for x do
ln -s "$x" /some/other/path/${x##*/};
done' {} +
Если это ваша настоящая команда find
, то find
здесь бесполезен. Смысл find
в рекурсии в подкаталоги. Нерекурсивный поиск иногда может быть полезен для использования его фильтров (например, для работы только с файлами определенного типа или измененными в течение определенного промежутка времени). Но нерекурсивная находка
без фильтрации бессмысленна.
for x in /some/path/*; do
ln -s "$x" "/some/other/path/${x##*/}";
done' {} +
Или
cd /some/path
for x in *; do
ln -s "$PWD/$x" "/some/other/path/$x";
done' {} +
Альтернативно, с помощью zsh :
autoload -U zmv
alias zln='zmv -L'
zln -s '/some/path/*' '/some/other/path/$f:t'