既存のディレクトリを上書きするBashスクリプトを作成しようとしています。したがって、ディレクトリfoo /があり、bar /を上書きしようとしています。しかし、私がそうするとき、
cp -Rf foo/ bar/
起こるのは、新しいbar/foo /ディレクトリが作成されることです。私はそれを望んでいません。 foo/aとbには2つのファイルがあります。 bar /にも同じ名前のファイルがあります。 foo/aとfoo/bをbar/aとbar/bに置き換えたい。
これを行うには、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
これで問題が解決するはずです。
2つの手順で行います。
rm -r bar/
cp -r foo/ bar/
bar/
がfoo/
と同一になるようにする場合は、代わりにrsync
を使用します。
rsync -a --delete foo/ bar/
いくつかの変更が行われた場合、ディレクトリ全体を削除して再コピーするよりもはるかに高速に実行されます。
-a
は「アーカイブモード」で、foo/
のファイルをbar/
に忠実にコピーします--delete
はfoo/
にない余分なファイルもbar/
から削除し、bar/
が同一になるようにします-vh
を追加してくださいfoo
の後のスラッシュは必須です。そうでない場合、rsync
はfoo/
自体を上書きするのではなく、bar/foo/
をbar/
にコピーします。foo/
のcontentsからbar/
のコンテンツに上書きするには、両方にスラッシュを使用します。neitherにスラッシュを付けても期待どおりに動作しないため、混乱します。 =、ただし、rsyncは、ソースパスにスラッシュがないことを尊重している場合でも、宛先パスを常にスラッシュがあると解釈します。したがって、自動追加されたスラッシュに一致させるために、ソースパスにスラッシュが必要です。宛先パスで、foo/
のcontentsをbar/
にコピーする場合は、ディレクトリfoo/
自体がbar/
にbar/foo
として到達するのではなく)rsync
は非常に強力で便利です。他に何ができるのか(sshをコピーするなど)を見て回るのに興味があるなら。
このcp
コマンドを使用します。
cp -Rf foo/* bar/
次のコマンドは、ドットファイル(隠しファイル)がコピーに含まれていることを確認します。
$ cp -Rf foo/. bar
@Jonathan Wheelerと非常によく似ています:
覚えたくないが、bar
を書き換えたくない場合:
rm -r bar/
cp -r foo/ !$
!$
は、前のコマンドの最後の引数を表示します。
次の2つのステップで構成されるコマンドを使用してみてください。
rm -rf bar && cp -r foo bar
定義した操作は「マージ」であり、cp
では実行できません。ただし、マージを探していない場合は、bar
フォルダーを失っても構いません。rm -rf bar
でフォルダーを削除し、mv foo bar
で名前を変更できます。両方の操作はファイルの内容ではなくファイルポインターによって行われるため、これには時間がかかりません。