Как перезаписать файлы-мишени с помощью mv?

У меня есть тонна файлов и dirs в подкаталоге, который я хочу переместить в родительский каталог. В целевом каталоге уже есть файлы и директории, которые необходимо перезаписать. Файлы, которые присутствуют только в цели, должны быть оставлены нетронутыми. Могу ли я заставить mv сделать это? Он ( mv * .. ) жалуется

 mv: cannot move `xyz' to `../xyz': Directory not empty 

Что мне не хватает?

  • Заменить пробелы и вкладки в конце строки во всех файлах
  • Есть ли программа «терминала», которая говорит с сервером через http?
  • Почему не работает wget url / mediafile.ext> medafile2.ext?
  • Ограничение доступа к файлам на внешнем диске
  • ожидаемое целочисленное выражение
  • Как заменить запятые на пробелы в csv, но вставляя другое количество пробелов после каждого столбца?
  • автозаполнение в сценарии оболочки
  • Могу ли я как-то добавить «&& prog2» к уже запущенному prog1?
  • Почему argv включает имя программы?
  • Импортировать файлы конфигурации VPN в NetworkManager из командной строки
  • Тройка> (процесс) обрезает его stdout при записи файла
  • Проверка статистики ping без остановки
  • 7 Solutions collect form web for “Как перезаписать файлы-мишени с помощью mv?”

    Вам придется скопировать их в пункт назначения, а затем удалить источник, используя команды cp -r * .. за которыми следует rm -rf * .

    Я не думаю, что вы можете «объединить» каталоги с помощью mv .

    rsync , вероятно, будет лучшим вариантом здесь. Это так же просто, как rsync -a subdir/ ./ .

    Мое тестовое дерево в filename : формат contents :

     ./file1:root ./file2:root ./dir/file3:dir ./dir/file4:dir ./subdir/dir/file3:subdir ./subdir/file1:subdir 

    Запуск rsync :

     $ rsync -a -v subdir/ ./ sending incremental file list ./ file1 dir/ dir/file3 

    дает:

     ./file1:subdir ./file2:root ./dir/file3:subdir ./dir/file4:dir ./subdir/dir/file3:subdir ./subdir/file1:subdir 

    И затем, чтобы эмулировать mv , вы, вероятно, захотите удалить исходный каталог:

     $ rm -r subdir/ 

    Предоставление:

     ./file1:subdir ./file2:parent ./dir/file3:subdir ./dir/file4:dir 

    Если это неверно, можете ли вы предоставить аналогичный пример (например, с помощью моего тестового дерева в верхней части этого ответа) с желаемым результатом?

    rsync может удалить источник после копирования с параметром --remove-source-files . Это должен быть удобный способ сделать то, что вы хотите.

    На rsync man page руководства rsync man page :

      --remove-source-files sender removes synchronized files (non-dir) 

    Вы можете сделать это с помощью cp и rm , но без копирования огромного количества данных, которые вы (предположительно) пытаетесь избежать переноса. @mattdm ссылается на это в своем комментарии , и ответ на другой вопрос дает более полное обсуждение различных вариантов.

     cp -rl source destination rm -r source 

    По сути, опция -l для команды cp создает жесткие ссылки на файлы, а не копирует их данные в новые файлы.

    Вот сценарий, который перемещает файлы из /path/to/source/root в соответствующий путь в /path/to/destination/root .

    • Если каталог существует как в источнике, так и в получателе, содержимое перемещается и объединяется рекурсивно.
    • Если файл или каталог существует в источнике, но не в месте назначения, он перемещается.
    • Любой файл или каталог, которые уже существуют в пункте назначения, остаются позади. (В частности, объединенные каталоги остаются в источнике. Это нелегко исправить.)

    Остерегайтесь, непроверенный код.

     export dest='/path/to/destination/root' cd /path/to/source/root find . -type d \( -exec sh -c '[ -d "$dest/$0" ]' \; -o \ -exec sh -c 'mv "$0" "$dest/$0"' {} \; -prune \) \ -o -exec sh -c ' if ! [ -e "$dest/$0" ]; then mv -f "$0" "$dest/$0" fi ' {} \; 

    Этот поток существует уже много лет и по-прежнему занимает 1 место в google, поэтому я хотел добавить другой метод. Как обычно я это делаю: упаковывая содержимое subdir в tarball, перемещая tarball до родительского каталога, а затем извлекаю его с поведением -overwrite по умолчанию. Это делает именно то, что вы ищете. Впоследствии вы можете удалить свой субдиректор.

     cd xyz tar -cvzpf tmp.tar.gz * mv tmp.tar.gz ../tmp.tar.gz cd .. tar -xvzpf tmp.tar.gz rm -rf xyz rm -f tmp.tar.gz 

    Если у вас достаточно памяти, вы можете сделать это следующим образом:

     mv -bfv directory_1/* directory_2/ # all duplicate source files/directories # will have ~ appended to them find -name "*~" -delete # will recursively find and delete all files # with ~ on the end 

    Убедитесь, что нет никаких важных файлов с ~ на конце, но если вы можете добавить --suffix=whateveryouwant а не по умолчанию.

    Linux и Unix - лучшая ОС в мире.