如何强制“cp”覆盖目录,而不是在其中创建另一个目录?

时间:2022-02-05 20:28:43

I'm trying to write a Bash script that will overwrite an existing directory. So, I have a directory foo/ and I am trying to overwrite bar/ with it. But when I do,

我正在尝试编写一个Bash脚本,它将覆盖现有的目录。我有一个目录foo/,我想用它覆盖bar/。但是当我做的,

cp -Rf foo/ bar/

what happens is that a new bar/foo/ directory is created. I don't want that. There are two files in foo/ a and b. There are files with same names in bar/ as well. I want the foo/a and foo/b to replace bar/a and bar/b.

所发生的是一个新的bar/foo/目录被创建。我不希望这样。foo/ a和b中有两个文件,bar/中也有同名的文件。我想要foo/a和foo/b取代bar/a和bar/b。

5 个解决方案

#1


56  

You can do this using -T option in cp.
See Man page for cp.

您可以在cp中使用-T选项。请参阅cp的手册页。

-T, --no-target-directory
    treat DEST as a normal file

So as per your example, following is the file structure.

正如您的示例所示,下面是文件结构。

$ tree test
test
|-- bar
|   |-- a
|   `-- b
`-- foo
    |-- a
    `-- b
2 directories, 4 files

You can see the clear difference when you use -v for Verbose.
When you use just -R option.

当您使用-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

When you use the option -T it overwrites the contents, treating the destination like a normal file and not directory.

当您使用选项-T时,它会覆盖内容,将目标视为普通文件,而不是目录。

$ cp -TRv foo/ bar/
`foo/b' -> `bar/b'
`foo/a' -> `bar/a'

$ tree
|-- bar
|   |-- a
|   `-- b
`-- foo
    |-- a
    `-- b
2 directories, 4 files

This should solve your problem.

这应该能解决你的问题。

#2


24  

Do it in two steps.

分两步做。

rm -r bar/
cp -r foo/ bar/

#3


6  

Use this cp command:

使用cp命令:

cp -Rf foo/* bar/

#4


4  

The following command ensures dotfiles (hidden files) are included in the copy:

下面的命令确保在副本中包含了dotfiles(隐藏文件):

$ cp -Rf foo/. bar

#5


1  

Very similar to @Jonathan Wheeler:

非常类似于@Jonathan Wheeler:

If you do not want to remember, but not rewrite bar:

如果你不想记住,但又不想重写吧:

rm -r bar/
cp -r foo/ !$

!$ displays the last argument of your previous command.

$将显示先前命令的最后一个参数。

#1


56  

You can do this using -T option in cp.
See Man page for cp.

您可以在cp中使用-T选项。请参阅cp的手册页。

-T, --no-target-directory
    treat DEST as a normal file

So as per your example, following is the file structure.

正如您的示例所示,下面是文件结构。

$ tree test
test
|-- bar
|   |-- a
|   `-- b
`-- foo
    |-- a
    `-- b
2 directories, 4 files

You can see the clear difference when you use -v for Verbose.
When you use just -R option.

当您使用-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

When you use the option -T it overwrites the contents, treating the destination like a normal file and not directory.

当您使用选项-T时,它会覆盖内容,将目标视为普通文件,而不是目录。

$ cp -TRv foo/ bar/
`foo/b' -> `bar/b'
`foo/a' -> `bar/a'

$ tree
|-- bar
|   |-- a
|   `-- b
`-- foo
    |-- a
    `-- b
2 directories, 4 files

This should solve your problem.

这应该能解决你的问题。

#2


24  

Do it in two steps.

分两步做。

rm -r bar/
cp -r foo/ bar/

#3


6  

Use this cp command:

使用cp命令:

cp -Rf foo/* bar/

#4


4  

The following command ensures dotfiles (hidden files) are included in the copy:

下面的命令确保在副本中包含了dotfiles(隐藏文件):

$ cp -Rf foo/. bar

#5


1  

Very similar to @Jonathan Wheeler:

非常类似于@Jonathan Wheeler:

If you do not want to remember, but not rewrite bar:

如果你不想记住,但又不想重写吧:

rm -r bar/
cp -r foo/ !$

!$ displays the last argument of your previous command.

$将显示先前命令的最后一个参数。