cp ‘та же файл’ ошибка при использовании -L с find и xargs

Вопрос или проблема

Я пытаюсь заменить символьные ссылки в своем текущем каталоге файлами, на которые они указывают. Я думал, что понимаю ‘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, что приводит к ошибке "файл уже существует". Давайте разберёмся подробно в вашей команде и предложим решение.

Анализ команды

Ваша команда выполняет ряд действий:

  1. Поиск символических ссылок:

    find ./ -maxdepth 1 -type l -regex ".*\(pdf\|odp\)"

    Эта часть ищет все символические ссылки в текущем каталоге, которые указывают на файлы с расширениями .pdf или .odp.

  2. Получение реальных путей:

    | xargs readlink -f

    Через xargs передаётся результат в команду readlink -f, которая выводит полный путь на файл, на который указывает символическая ссылка.

  3. Копирование файлов:

    | 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 не позволяет это сделать, поскольку это приведёт к перезаписи.

Решение проблемы

Чтобы избежать данной ошибки, вы можете использовать несколько различных подходов:

  1. Удаление существующих файлов: Перед копированием можно удалить существующие файлы:

    find ./ -maxdepth 1 -type l -regex ".*\(pdf\|odp\)" | xargs readlink -f | xargs -I {} bash -c 'rm -f ./$(basename {}) && cp -Lf "{}" .'

    В этом случае, перед копированием, мы удаляем файл с тем же именем в текущем каталоге.

  2. Проверка существования файла: Добавьте проверку, чтобы не копировать файлы, если они уже существуют:

    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

    В этом варианте, перед копированием мы проверяем, существует ли файл с таким же именем в текущем каталоге. Если его нет, файл копируется.

Заключение

Используя один из предложенных методов, вы сможете заменить символические ссылки на файлы, не сталкиваясь с ошибкой копирования. Убедитесь, что вы также проверяете пути и имена файлов, чтобы избежать других потенциальных конфликтов.

Оцените материал
Добавить комментарий

Капча загружается...