2014-05-16 38 views
43

我想寫一個Bash腳本來覆蓋現有的目錄。所以,我有一個目錄foo /,我正試圖用它覆蓋欄/ /。但是當我這樣做時,如何強制'cp'覆蓋目錄而不是在裏面創建另一個目錄?

cp -Rf foo/ bar/ 

發生什麼是一個新的bar/foo /目錄被創建。我不想那樣。 foo/a和b中有兩個文件。在bar /中有相同名稱的文件。我想要foo/a和foo/b來替換bar/a和bar/b。

回答

5

使用此命令cp

cp -Rf foo/* bar/ 
+4

這不會刪除存在於bar但不存在於foo中的文件。 – Ara

+1

不知道你是什麼意思。爲什麼'cp'命令要從源文件中刪除文件? – anubhava

+0

我的理解是,當你'用另一個覆蓋現有目錄'時,最後被覆蓋的目錄應該是另一個的副本。 也就是說在結束欄應該是foo的副本,就像@ jonathan-wheeler答案一樣,但如果你有一個文件欄/ c而沒有foo/c,那麼bar/c不會被刪除。 在附註中,我剛剛注意到Saurabh Meshram的答案並非如此。 – Ara

19

做它在兩個步驟。

rm -r bar/ 
cp -r foo/ bar/ 
+0

這個他認爲他想要一個命令,但這看起來沒問題。 –

+7

這實際上是迄今爲止僅給出的**示例,它將確保'bar'與'foo'的內容完全相同,而不是'foo'的項目與可能已經存在於'bar中的其他項目的組合'。來自@Saurabh Meshram的高度迴應的問題存在這個問題。 – robo

+1

使用此功能時要格外小心,因爲它會*刪除所有文件,甚至隱藏文件。 –

52

可以在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 

這應該可以解決您的問題。

+9

只是爲了防止任何人因此而被絆倒,它將不適用於OSX cp https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages /man1/cp.1.html – dnfehren

+5

儘管上面給出的例子掩蓋了這個問題,但這個答案是OP所要查找的並不清楚......使用-T選項,現有目標文件('bar /'),但源代碼中的* not *('foo /')將保留原位,所以這不是大多數人認爲完全覆蓋目錄的原因。 即。如果已經存在'bar/baz',它將在之後存在... – robo

+0

在這個過程中沒有選項可以清除目標文件夾嗎?我不敢相信! – JohnyTex

3

下面的命令,確保點文件(隱藏文件)都包含在副本:

$ cp -Rf foo/. bar 
+1

這是真的嗎?看起來不尋常。 – Mateng

+2

@Mateng我剛測試過它 - 是的,它是真的。 – Matmarbon

1

非常相似,@Jonathan惠勒:

如果你不想記住,但不能重寫bar

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

!$顯示你的前一個命令的最後一個參數。

+1

關於!$的提示太棒了! –

相關問題