Вопрос или проблема
Я пытаюсь заменить символьные ссылки в своем текущем каталоге файлами, на которые они указывают. Я думал, что понимаю ‘cp’ и аргумент ‘-L’, но, похоже, нет.
Вот команда, которую я использую
find ./ -maxdepth 1 -type l -regex ".*\(pdf\|odp\)" | xargs readlink -f | xargs cp -Lf -t .
Вот ошибка, которую я получаю
cp: '/home/user/dir1/dir2/dir3/file.pdf' и './file.pdf' являются одним и тем же файлом
Что я пропускаю
Ответ или решение
Ваша проблема заключается в том, что вы пытаетесь скопировать файл из одной папки в ту же папку с помощью команды cp
, что приводит к ошибке "файл уже существует". Давайте разберёмся подробно в вашей команде и предложим решение.
Анализ команды
Ваша команда выполняет ряд действий:
-
Поиск символических ссылок:
find ./ -maxdepth 1 -type l -regex ".*\(pdf\|odp\)"
Эта часть ищет все символические ссылки в текущем каталоге, которые указывают на файлы с расширениями
.pdf
или.odp
. -
Получение реальных путей:
| xargs readlink -f
Через
xargs
передаётся результат в командуreadlink -f
, которая выводит полный путь на файл, на который указывает символическая ссылка. -
Копирование файлов:
| xargs cp -Lf -t .
Наконец, команда
cp -Lf -t .
пытается скопировать данные файлы в текущий каталог.
Причина ошибки
Ошибка cp: '/home/user/dir1/dir2/dir3/file.pdf' and './file.pdf' are the same file
возникает, когда cp
пытается скопировать файл, который уже существует в текущем каталоге с тем же именем. Параметр -L
сообщает cp
следовать за символическими ссылками, но если файл уже существует с тем же именем, cp
не позволяет это сделать, поскольку это приведёт к перезаписи.
Решение проблемы
Чтобы избежать данной ошибки, вы можете использовать несколько различных подходов:
-
Удаление существующих файлов: Перед копированием можно удалить существующие файлы:
find ./ -maxdepth 1 -type l -regex ".*\(pdf\|odp\)" | xargs readlink -f | xargs -I {} bash -c 'rm -f ./$(basename {}) && cp -Lf "{}" .'
В этом случае, перед копированием, мы удаляем файл с тем же именем в текущем каталоге.
-
Проверка существования файла: Добавьте проверку, чтобы не копировать файлы, если они уже существуют:
find ./ -maxdepth 1 -type l -regex ".*\(pdf\|odp\)" | xargs readlink -f | while read file; do basename=$(basename "$file") if [ ! -e "./$basename" ]; then cp -Lf "$file" . fi done
В этом варианте, перед копированием мы проверяем, существует ли файл с таким же именем в текущем каталоге. Если его нет, файл копируется.
Заключение
Используя один из предложенных методов, вы сможете заменить символические ссылки на файлы, не сталкиваясь с ошибкой копирования. Убедитесь, что вы также проверяете пути и имена файлов, чтобы избежать других потенциальных конфликтов.