Как скопировать в cp, если папка назначения уже существует?

Пример ...

Это то, что я хочу.

/tmp $ cp -f -R --verbose /tmp/a /tmp/b
`/tmp/a' -> `/tmp/b'
`/tmp/a/file2' -> `/tmp/b/file2'
`/tmp/a/file1' -> `/tmp/b/file1'

Это то, чего я не хочу.

/tmp $ cp -f -R --verbose /tmp/a /tmp/b
`/tmp/a' -> `/tmp/b/a'
`/tmp/a/file2' -> `/tmp/b/a/file2'
`/tmp/a/file1' -> `/tmp/b/a/file1'

Как я могу позволить cp вести себя так, как будто папка еще не существует?

(Я не хочу удалять ее заранее. Просто некоторые файлы из / tmp / a нужно скопировать в / tmp / b без создания подпапки a внутри / tmp / b. Таким образом, это выглядит как / tmp / b / file1 / tmp / b / file2 и т. д.)

8
задан 1 February 2013 в 23:58

4 ответа

Флаг -T (AKA --no-target-directory) делает то, что вы хотите:

$ cp -R --verbose -T /tmp/a /tmp/b
`/tmp/a/file1' -> `/tmp/b/file1'
`/tmp/a/file2' -> `/tmp/b/file2'
0
ответ дан 1 February 2013 в 23:58

Предполагая, что Bash вы можете сделать

( shopt -s dotglob; cp -f -R --verbose /tmp/a/* /tmp/b/ )

, то, что он делает:

  1. он будет гарантировать, что globs (*) ловят файлы с точкой впереди. Они считаются «скрытыми» по соглашению.
  2. * расширится до того, как cp увидит команду. Таким образом, если есть два файла, как в вашем вопросе, расширенная командная строка будет иметь вид cp -f -R --verbose /tmp/a/file1 /tmp/a/file1 /tmp/b/
  3. , и, наконец, завершающая обратная косая черта в месте назначения гарантирует, что он скопирует в эту папку /tmp/b/.

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

0
ответ дан 1 February 2013 в 23:58

Rsync был изобретен для такого рода вещей.

rsync -av --update /source/ /destination

Примечание: обратите внимание, что / source / имеет завершающий символ "/", который выбирает file1, file2, а не папку, в которой он находится. / Destination не имеет завершающий элемент. Итак, ваше решение выглядит так:

rsync -av --update /tmp/a/ /tmp/b
0
ответ дан 1 February 2013 в 23:58
$ cp -r --verbose a/. b
`a/.' -> `b'
`a/./zzz' -> `b/zzz'

$ cp -r --verbose a/. b
`a/./zzz' -> `b/./zzz'

Я не думаю, что видел это описанное где-либо; Я просто пробовал разные возможности и нашел тот, который сработал. Насколько я знаю, это естественное следствие того, как работают /. и cp. (В отличие от синтаксиса для rsync, упомянутого в другом ответе, который явно задокументирован как особый случай).

0
ответ дан 1 February 2013 в 23:58

Другие вопросы по тегам:

Похожие вопросы: