
Я пытаюсь использовать find для создания кучи символических ссылок, но использование результата с {} включает ./ перед каждым именем файла. Как мне этого избежать?
find . -type l -name '*.h' -exec ln -s /sourcedir/{} /destinationdir/{} \;
решение1
Вам нужно изменить только один символ в вашей команде:
find * -type l -name '*.h' -exec ln -s /sourcedir/{} /destinationdir/{} \;
# ^
решение2
Используйте стандартный синтаксис, например:
S=/sourcedir D=/destdir find . -type l -name '*.h' -exec sh -c '
for i do
ln -s -- "$S${i#.}" "$D/$i"
done' sh {} +
Если вы хотите использовать GNUisms, вы можете сделать следующее:
find . -type l -name '*.h' -printf '/sourcedir/%P\0/destdir/%P\0' |
xargs -r0n2 ln -s
Или если/sourcedir
являетсятекущий каталог:
find "$PWD" -type l -name '*.h' -printf '%p\0/destdir/%P\0' |
xargs -r0n2 ln -s
решение3
find
выведет имена относительно путей, которые вы указали в качестве аргументов. В этом случае путь — .
, поэтому все имена будут начинаться с ./
. Чтобы получить абсолютные пути, вам необходимо указать абсолютный путь в качестве входных данных:
find "$PWD" -type l -name '*.h'
Эта команда использует $PWD
переменную окружения, которая содержит абсолютный путь к текущему рабочему каталогу, поэтому она должна сохранить значение вашей исходной команды.
решение4
find . -type l -name '*.h' -print0 | cut -z -c3- \
| xargs -0 -I '{}' ln -s '/sourcedir/{}' '/destinationdir/{}'
-print0
вывести полное имя файла на стандартный вывод, за которым следуетnull
символ.
man cut
- удалить разделы из каждой строки файлов
-z
Разделителем строк являетсяNUL
, а не символ новой строки.-c
выберите только эти символы.N-
от N-го байта, символа или поля, отсчитываемого от 1, до конца строки.
man xargs
- создавать и выполнять командные строки из стандартного ввода.
xargs [options] [command [initial-arguments]]
-0
Входные элементы завершаются символомnull
, а не пробелом, а кавычки и обратная косая черта не являются специальными (каждый символ воспринимается буквально).-I replace-str
Заменить вхожденияreplace-str
вinitial-arguments
на имена, считанные из стандартного ввода. Кроме того, не заключенные в кавычки пробелы не завершают элементы ввода; вместо этого разделителем является символ новой строки. Подразумевает-L 1
.-L max-lines
Используйте не болееmax-lines
непустых строк ввода в каждой командной строке.