Как заставить "cp" перезаписать каталог вместо создания другого внутри?
Я пытаюсь написать Bash script, который перезапишет существующий каталог. Итак, у меня есть каталог foo/, и я пытаюсь перезаписать его с помощью bar/. Но когда я это делаю,
cp -Rf foo/ bar/
происходит то, что создается новый каталог bar/foo/. Я не хочу этого. В файлах foo/a и b есть два файла. В барах также есть файлы с одинаковыми именами. Я хочу, чтобы foo/a и foo/b заменили bar/a и bar/b.
Ответы
Ответ 1
Вы можете сделать это, используя опцию -T
в cp
.
См. Страницу "Человек" для cp
.
-T, --no-target-directory
treat DEST as a normal file
В соответствии с вашим примером следующая структура файла.
$ tree test
test
|-- bar
| |-- a
| `-- b
`-- foo
|-- a
`-- b
2 directories, 4 files
Вы можете видеть явное различие при использовании -v
для Verbose.
Когда вы используете только параметр -R
.
$ cp -Rv foo/ bar/
`foo/' -> `bar/foo'
`foo/b' -> `bar/foo/b'
`foo/a' -> `bar/foo/a'
$ tree
|-- bar
| |-- a
| |-- b
| `-- foo
| |-- a
| `-- b
`-- foo
|-- a
`-- b
3 directories, 6 files
Когда вы используете опцию -T
, она перезаписывает содержимое, обрабатывает назначение как обычный файл, а не каталог.
$ cp -TRv foo/ bar/
`foo/b' -> `bar/b'
`foo/a' -> `bar/a'
$ tree
|-- bar
| |-- a
| `-- b
`-- foo
|-- a
`-- b
2 directories, 4 files
Это должно решить вашу проблему.
Ответ 2
Сделайте это в два этапа.
rm -r bar/
cp -r foo/ bar/
Ответ 3
Используйте эту команду cp
:
cp -Rf foo/* bar/
Ответ 4
Следующая команда обеспечивает, чтобы в копии были включены dotfiles (скрытые файлы):
$ cp -Rf foo/. bar
Ответ 5
Если вы хотите, чтобы bar/
заканчивался идентичным foo/
, вместо этого используйте rsync
:
rsync -a --delete foo/ bar/
Если только несколько вещей изменились, это будет выполняться намного быстрее, чем удаление и повторное копирование всего каталога.
-
-a
- это "режим архива", который точно копирует файлы в foo/
to bar/
-
--delete
удаляет файлы не в foo/
from bar/
- Если вы хотите посмотреть, что он делает, добавьте
-vh
для подробного и -vh
для человека - Примечание: требуется косая черта после
foo
, иначе rsync
скопирует foo/
в bar/foo/
вместо того, чтобы переписать bar/
self
rsync
очень мощный и полезный, если вам любопытно посмотреть, что еще он может сделать (например, копирование через ssh).
Ответ 6
Очень похоже на @Jonathan Wheeler:
Если вы не хотите помнить, но не переписываете bar
:
rm -r bar/
cp -r foo/ !$
!$
отображает последний аргумент предыдущей команды.