我想写一个Bash脚本,用于覆盖现有的目录。我有一个名为foo/
的目录,并且我正在尝试用它来覆盖bar/
。但是当我这样做时:
cp -Rf foo/ bar/
创建了一个新的bar/foo/
目录,我不想要它。在foo/
中有两个文件;a
和b
。在bar/
中也有相同名称的文件。我希望foo/a
和foo/b
替换bar/a
和bar/b
。
我想写一个Bash脚本,用于覆盖现有的目录。我有一个名为foo/
的目录,并且我正在尝试用它来覆盖bar/
。但是当我这样做时:
cp -Rf foo/ bar/
创建了一个新的bar/foo/
目录,我不想要它。在foo/
中有两个文件;a
和b
。在bar/
中也有相同名称的文件。我希望foo/a
和foo/b
替换bar/a
和bar/b
。
cp
命令的-T
选项来完成此操作。cp
命令的Man手册。-T, --no-target-directory
treat DEST as a normal file
根据您的示例,以下是文件结构。
$ tree test
test
|-- bar
| |-- a
| `-- b
`-- foo
|-- a
`-- b
2 directories, 4 files
当您使用-v
(详细信息)选项时,您可以看到明显的差异。
当您只使用-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
如果您想确保bar/
与foo/
完全相同,请使用rsync
:
rsync -a --delete foo/ bar/
如果只有一些内容发生了变化,使用这种方法比删除并重新复制整个目录要快得多。
-a
是“归档模式”,它将foo/
中的文件忠实地复制到bar/
中--delete
也会从bar/
中删除不在foo/
中的额外文件,确保bar/
最终与foo/
相同-vh
来查看详细和易读的信息foo
后面加上斜杠是必需的,否则rsync
会将foo/
复制到bar/foo/
而不是覆盖bar/
本身。
foo/
的内容覆盖到bar/
的内容,我们在两个目录名后都使用了一个斜杠。这是令人困惑的,因为如果两个目录名后都不加斜杠,它将不会按预期工作;rsync总是偷偷地将目标路径解释为带有斜杠,即使它遵循源路径上斜杠的缺失。因此,如果我们想要将foo/
的内容复制到bar/
中,而不是将目录foo/
本身放置到bar/
中作为bar/foo
,我们需要在源路径上加上斜杠,以使其与自动添加斜杠的目标路径匹配)。rsync
非常强大和有用,如果你感兴趣,可以找找它还能做什么(例如通过ssh进行复制)。
cp -T
选项,因为它也适用于macOS系统。 - tongueroo分两步来做。
rm -r bar/
cp -r foo/ bar/
bar
的内容与 foo
完全相同,而不是由 foo
中的项加上已经存在于 bar
中的其他项组成。下面 @Saurabh Meshram 得到高赞的答案就存在这个问题。 - robocp -r foo/ !$```
- Michael Dimmittfoo
和 bar
是大型目录...也许在 bar
中有一些文件不在 foo
中,你不想删除它们。我认为这不应该被视为一个现实的答案。 - Assimilater使用这个cp
命令:
cp -Rf foo/* bar/
cp
命令会从源文件中删除文件?请问能否解释一下? - anubhavashopt
进行控制。 - anubhava以下命令可以确保复制中包括点文件(隐藏文件):
$ cp -Rf foo/. bar
-a
或-p
一起使用,这也确保目标目录接收源目录的元数据(所有者、权限)--非常好! - schlimmchen和@Jonathan Wheeler非常相似:
如果你不想记住,但不想重新编写bar
:
rm -r bar/
cp -r foo/ !$
!$
显示你上一个命令的最后一个参数。
\cp -rf foo/* bar/
robocopy 路径/到/源路径 路径/到/目标路径 -MIR
-MIR
表示镜像,它将生成两个相同的文件夹。现有文件将被跳过,额外的文件将被删除。
cp
进行操作。但是,如果您不需要合并,并且可以删除文件夹bar
,那么您可以简单地使用rm -rf bar
删除该文件夹,然后使用mv foo bar
重命名它。这不会花费任何时间,因为这两个操作都是通过文件指针完成的,而不是文件内容。尝试使用这个命令:
cp -Rf foo/* bar/
bar/
)中但在源(foo/
)中不存在的文件将被保留在原地,因此大多数人不会认为这是完全覆盖目录。也就是说,如果bar/baz
已经存在,执行操作后它仍将存在... - roborm -rf bar/* && cp -TRv foo/ bar/
- theferrit32