web-dev-qa-db-ja.com

内部に別のディレクトリを作成する代わりに、「cp」がディレクトリを上書きするように強制するにはどうすればよいですか?

既存のディレクトリを上書きするBashスクリプトを作成しようとしています。したがって、ディレクトリfoo /があり、bar /を上書きしようとしています。しかし、私がそうするとき、

cp -Rf foo/ bar/

起こるのは、新しいbar/foo /ディレクトリが作成されることです。私はそれを望んでいません。 foo/aとbには2つのファイルがあります。 bar /にも同じ名前のファイルがあります。 foo/aとfoo/bをbar/aとbar/bに置き換えたい。

74
saketrp

これを行うには、cp-Tオプションを使用します。
cpのマニュアルページを参照してください。

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

あなたの例によると、ファイル構造は次のとおりです。

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

Verboseに-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

これで問題が解決するはずです。

90
Saurabh Meshram

2つの手順で行います。

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

bar/foo/と同一になるようにする場合は、代わりにrsyncを使用します。

rsync -a --delete foo/ bar/

いくつかの変更が行われた場合、ディレクトリ全体を削除して再コピーするよりもはるかに高速に実行されます。

  • -aは「アーカイブモード」で、foo/のファイルをbar/に忠実にコピーします
  • --deletefoo/にない余分なファイルもbar/から削除し、bar/が同一になるようにします
  • それが何をしているのかを見たいなら、冗長で人間が読めるように-vhを追加してください
  • 注:fooの後のスラッシュは必須です。そうでない場合、rsyncfoo/自体を上書きするのではなく、bar/foo/bar/にコピーします。
    • (rsyncのディレクトリの後のスラッシュは紛らわしい。興味があるなら、ここにスクープがある。それらは、ディレクトリitselfではなく、ディレクトリのcontentsを参照するようにrsyncに指示する。したがって、foo/contentsからbar/のコンテンツに上書きするには、両方にスラッシュを使用します。neitherにスラッシュを付けても期待どおりに動作しないため、混乱します。 =、ただし、rsyncは、ソースパスにスラッシュがないことを尊重している場合でも、宛先パスを常にスラッシュがあると解釈します。したがって、自動追加されたスラッシュに一致させるために、ソースパスにスラッシュが必要です。宛先パスで、foo/contentsbar/にコピーする場合は、ディレクトリfoo/自体がbar/bar/fooとして到達するのではなく)

rsyncは非常に強力で便利です。他に何ができるのか(sshをコピーするなど)を見て回るのに興味があるなら。

17
Tom Potter

このcpコマンドを使用します。

cp -Rf foo/* bar/
10
anubhava

次のコマンドは、ドットファイル(隠しファイル)がコピーに含まれていることを確認します。

$ cp -Rf foo/. bar
7
Brynn Mahsman

@Jonathan Wheelerと非常によく似ています:

覚えたくないが、barを書き換えたくない場合:

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

!$は、前のコマンドの最後の引数を表示します。

3
Michael Dimmitt

次の2つのステップで構成されるコマンドを使用してみてください。

rm -rf bar && cp -r foo bar
0
Yahor M

定義した操作は「マージ」であり、cpでは実行できません。ただし、マージを探していない場合は、barフォルダーを失っても構いません。rm -rf barでフォルダーを削除し、mv foo barで名前を変更できます。両方の操作はファイルの内容ではなくファイルポインターによって行われるため、これには時間がかかりません。

0
atiyil