![如果目标文件夹已经存在,如何使用 cp 复制到?](https://linux22.com/image/830775/%E5%A6%82%E6%9E%9C%E7%9B%AE%E6%A0%87%E6%96%87%E4%BB%B6%E5%A4%B9%E5%B7%B2%E7%BB%8F%E5%AD%98%E5%9C%A8%EF%BC%8C%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20cp%20%E5%A4%8D%E5%88%B6%E5%88%B0%EF%BC%9F.png)
例子...
这就是我要的。
/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 中,而不在 /tmp/b 内创建子文件夹 a。因此它看起来像 /tmp/b/file1 /tmp/b/file2 等等。)
答案1
该-T
标志(又名--no-target-directory
)可以执行您想要的操作:
$ cp -R --verbose -T /tmp/a /tmp/b
`/tmp/a/file1' -> `/tmp/b/file1'
`/tmp/a/file2' -> `/tmp/b/file2'
答案2
假设 Bash 你可以这样做
( shopt -s dotglob; cp -f -R --verbose /tmp/a/* /tmp/b/ )
这样做的目的是:
- 它将确保 glob(
*
)捕获前面带有点的文件。按照惯例,它们被视为“隐藏”。 *
cp
将在看到命令之前展开。因此,如果有两个文件(如您的问题中所述),则展开的命令行将是cp -f -R --verbose /tmp/a/file1 /tmp/a/file1 /tmp/b/
- 最后,目标上的尾部反斜杠确保它复制进入那个文件夹
/tmp/b/
。
此方法还确保您不必重置 shell 选项,因为它是在子 shell 中运行的。您可以将其放入脚本文件而不是从命令行执行,从而获得类似的结果。
答案3
Rsync 就是为了解决这种问题而发明的。
rsync -av --update /source/ /destination
注意:请注意,/source/ 末尾有一个“/”,它表示选择 file1、file2,而不是其所在的文件夹。/destination 没有末尾。因此您的解决方案如下所示:
rsync -av --update /tmp/a/ /tmp/b
答案4
$ cp -r --verbose a/. b
`a/.' -> `b'
`a/./zzz' -> `b/zzz'
$ cp -r --verbose a/. b
`a/./zzz' -> `b/./zzz'
我认为我从未在任何地方看到过这种描述;我只是尝试了不同的可能性,并找到了一种可行的方法。据我所知,这是如何/.
和cp
工作的自然结果。(与另一个答案中提到的语法相反rsync
,该语法明确记录为特殊情况)。