我想寫一個Bash腳本來覆蓋現有的目錄。所以,我有一個目錄foo /,我正試圖用它覆蓋欄/ /。但是當我這樣做時,如何強制'cp'覆蓋目錄而不是在裏面創建另一個目錄?
cp -Rf foo/ bar/
發生什麼是一個新的bar/foo /目錄被創建。我不想那樣。 foo/a和b中有兩個文件。在bar /中有相同名稱的文件。我想要foo/a和foo/b來替換bar/a和bar/b。
我想寫一個Bash腳本來覆蓋現有的目錄。所以,我有一個目錄foo /,我正試圖用它覆蓋欄/ /。但是當我這樣做時,如何強制'cp'覆蓋目錄而不是在裏面創建另一個目錄?
cp -Rf foo/ bar/
發生什麼是一個新的bar/foo /目錄被創建。我不想那樣。 foo/a和b中有兩個文件。在bar /中有相同名稱的文件。我想要foo/a和foo/b來替換bar/a和bar/b。
使用此命令cp
:
cp -Rf foo/* bar/
做它在兩個步驟。
rm -r bar/
cp -r foo/ bar/
這個他認爲他想要一個命令,但這看起來沒問題。 –
這實際上是迄今爲止僅給出的**示例,它將確保'bar'與'foo'的內容完全相同,而不是'foo'的項目與可能已經存在於'bar中的其他項目的組合'。來自@Saurabh Meshram的高度迴應的問題存在這個問題。 – robo
使用此功能時要格外小心,因爲它會*刪除所有文件,甚至隱藏文件。 –
可以在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
當您爲詳細使用-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
這應該可以解決您的問題。
只是爲了防止任何人因此而被絆倒,它將不適用於OSX cp https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages /man1/cp.1.html – dnfehren
儘管上面給出的例子掩蓋了這個問題,但這個答案是OP所要查找的並不清楚......使用-T選項,現有目標文件('bar /'),但源代碼中的* not *('foo /')將保留原位,所以這不是大多數人認爲完全覆蓋目錄的原因。 即。如果已經存在'bar/baz',它將在之後存在... – robo
在這個過程中沒有選項可以清除目標文件夾嗎?我不敢相信! – JohnyTex
非常相似,@Jonathan惠勒:
如果你不想記住,但不能重寫bar
:
rm -r bar/
cp -r foo/ !$
!$
顯示你的前一個命令的最後一個參數。
關於!$的提示太棒了! –
這不會刪除存在於bar但不存在於foo中的文件。 – Ara
不知道你是什麼意思。爲什麼'cp'命令要從源文件中刪除文件? – anubhava
我的理解是,當你'用另一個覆蓋現有目錄'時,最後被覆蓋的目錄應該是另一個的副本。 也就是說在結束欄應該是foo的副本,就像@ jonathan-wheeler答案一樣,但如果你有一個文件欄/ c而沒有foo/c,那麼bar/c不會被刪除。 在附註中,我剛剛注意到Saurabh Meshram的答案並非如此。 – Ara