İçinde başka bir dizin oluşturmak yerine 'cp' dizinin üzerine yazmaya nasıl zorlanır?


107

Mevcut bir dizinin üzerine yazacak bir Bash betiği yazmaya çalışıyorum. Bir rehberim var foo/ve üzerine yazmaya çalışıyorum bar/. Ama bunu yaptığımda:

cp -Rf foo/ bar/

yeni bir bar/foo/dizin oluşturulur. Ben bunu istemiyorum İçinde iki dosya var foo/; ave b. İçinde aynı ada sahip dosyalar bar/da var. İstediğim foo/ave foo/byerine bar/ave bar/b.

Yanıtlar:


123

Bunu içindeki -Tseçeneği kullanarak yapabilirsiniz cp.
İçin Man sayfasına bakın cp.

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

Dolayısıyla, örneğinize göre, dosya yapısı aşağıdadır.

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

-vVerbose için kullandığınızda net farkı görebilirsiniz .
Sadece -Rseçeneği kullandığınızda .

$ 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

Bu seçeneği kullandığınızda, hedefe dizin değil normal bir dosya gibi davranarak-T içeriğin üzerine yazar .

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

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

Bu probleminizi çözmeli.


22
herhangi birinin buna
takılması durumunda

9
Yukarıda verilen örnekler sorunu maskelese de, bu cevabın OP'nin aradığı şey olduğu net değil ... -T seçeneği ile, mevcut bir hedef ( bar/) içinde olan ancak kaynakta ( ) olmayan dosyalar foo/bırakılacaktır. yerinde olduğundan, çoğu insanın dizinin tamamen üzerine yazılmasını düşündüğü şey bu değildir. yani. bar/bazzaten varsa , daha sonra da var olacaktı ...
robo

1
Bu cevap op sorusuna cevap verir, ancak hedef zaten mevcutsa ve içerdiği içeriği kaldırmak istiyorsanız, ancak kaynak dizini kaldırmıyorsa durumu ele almaz. Bu, dosyaları bir yerden diğerine kopyalamak için beklenen bir davranış değildir. Sadece kaynakta bulunan hedef şeylerin üzerine yazar, hedefte kaynakta olmayan hiçbir şeye dokunmaz. Bunu yapmak için başına bir komut ekleyerek hedef klasörü temizleyebilirsiniz:rm -rf bar/* && cp -TRv foo/ bar/
theferrit32

2
Ben bir zihin okuyucusu değilim ... OP'nin ne aradığını daha fazla açıklığa kavuşturmuyorum, ancak bu KESİNLİKLE (MEEEE) aradığım cevaptı
Assimilater

2
en çok oy verilen yorumdaki bağlantının neden çalışmadığına dair herhangi birinin tetiklenmesi durumunda, işte burada: web.archive.org/web/20170909193852/https://developer.apple.com/…
Sulphur

48

Bunu iki adımda yapın.

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

11
Bu aslında şu ana kadar verilen tek örnektir bar, içerik olarak aynı olduğunu garanti eder , artı diğer öğelerin içinde zaten var fooolan öğelerin bir kombinasyonu değil . Aşağıdaki @Saurabh Meshram'dan yüksek oy alan cevapta bu sorun var. foobar
robo

1
O kadar, bu kullanarak ekstra dikkatli olun edecek bar, hatta gizli olanlara kadar tüm dosyaları kaldırmak.
Elia Grady

mac osx: rm -rf bar/; cp -r foo/ !$
Michael Dimmitt

1
Bu her zaman geçerli ... veya arzu ... eğer hayal değil foove barbüyük dizinleri vardır ... belki dosyalar vardır bar, değil fookaldırmak istemiyorum. Bu gerçekçi bir cevap imho olarak görülmemeli
Assimilater

Benim için çalışmasına rağmen, en iyi çözüm değil, çünkü foo'ya dahil edilmiş / ancak barda olmayan / bunu yaptıktan sonra silinecek olan dosya olabilir.
Nitwit

47

bar/Uçların aynı olmasını sağlamak istiyorsanız foo/, rsyncbunun yerine şunu kullanın:

rsync -a --delete foo/ bar/

Yalnızca birkaç şey değiştiyse, bu, tüm dizini kaldırıp yeniden kopyalamaktan çok daha hızlı gerçekleşecektir.

  • -asadakatle içinde dosyaları kopyalar 'arşiv modu' olduğu foo/içinbar/
  • --deletedeğil ekstra dosyaları siler foo/gelen bar/yanı, sağlanması bar/uçları özdeş kadar
  • Ne yaptığını görmek istiyorsanız, -vhayrıntılı ve insan tarafından okunabilir için ekleyin
  • Not: sonra eğik çizgi foogereklidir, aksi rsynckopyalar foo/için bar/foo/üzerine yazma yerine bar/kendisini.
    • (Rsync'de dizinleri sonra Bölü karıştırıyorsun, siz, burada kepçe ilgileniyor iseniz Onlar başvurmak için Rsync. İçeriğinden dizin yerine, dizinin kendisi Yani dan üzerine yazmak. İçeriklerin ait foo/içerikleri üzerine bar/biz, Her ikisinde de eğik çizgi kullanın. Bu kafa karıştırıcıdır çünkü hiçbirinde eğik çizgi ile beklendiği gibi çalışmaz ; rsync, kaynakta eğik çizgi olmamasına rağmen, hedef yolu sinsice her zaman bir bölü çizgisi varmış gibi yorumlar. biz kopyalamak istiyorsanız yolu. biz kaynak yolunda bir çizgi ihtiyaç Yani, hedef yolunda otomatik eklenen çizgi maç yapmak için içeriğini arasında foo/içine bar/dizin yerine,foo/kendisine iniş bar/olarak bar/foo).

rsync çok güçlü ve kullanışlıdır, merak ediyorsanız, başka neler yapabileceğini merak ediyorsanız (ssh üzerinden kopyalamak gibi).


1
Bu cevabı cp -Tseçenekten daha iyi beğenin çünkü macosx üzerinde de çalışıyor 👍
tongueroo

18

Bu cpkomutu kullanın :

cp -Rf foo/* bar/

9
Bu, çubukta bulunan ancak foo'da bulunmayan dosyaları kaldırmaz.
Ara

5
Bununla ne demek istediğini bilmiyorum. cpKomut neden dosyayı kaynaktan kaldırmalı?
anubhava

Anladığım kadarıyla, 'var olan bir dizinin üzerine başka bir dizin yazdığınızda', üzerine yazılan dizinin diğerinin bir kopyası olması gerektiğiydi. Yani, @ jonathan-wheeler cevabında olduğu gibi, son çubukta foo'nun bir kopyası olmalıdır, ancak bir dosya bar / c varsa ve foo / c yoksa, bar / c silinmez. Bir yan not olarak, Saurabh Meshram'ın cevabında da durumun böyle olmadığını fark ettim.
Ara

Belki üzerine yazmanın ne anlama geldiği konusunda hemfikir değiliz, benim için temelde değiştirirken, sen megre anlamına gelebilir mi? OP'nin tam olarak ne istediğini söylemek zor çünkü sadece hem foo hem de bar'da olan 2 dosyadan bahsetmişti.
Ara

Bu sözdizimi ayrıca gizli nokta dosyalarını da yok sayar. Büyük bir sayı da küreyi patlatabilir.
xpusostomos

13

Aşağıdaki komut, nokta dosyalarının (gizli dosyalar) kopyaya dahil edilmesini sağlar:

$ cp -Rf foo/. bar

1
Bu doğru mu? Sıradışı görünüyor.
Mateng

2
@Mateng Daha yeni test ettim - evet bu doğru.
Matmarbon

1
.dizindeki tüm dosyalar anlamına gelir. Bu nedenle, doğal olarak gizli dosyalar dahil edilecektir.
Jaspreet Singh

Aslında oldukça zarif. Linux'ta "cp -RTf foo bar" da yapabilirsiniz.
xpusostomos

6

@Jonathan Wheeler'a çok benzer:

Hatırlamak istemiyor ama yeniden yazmak istemiyorsanız bar:

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

!$ önceki komutunuzun son bağımsız değişkenini gösterir.


5
! $ İle ilgili ipucu harika!
Lucas Morgan

0

bu probleminizi çözmeli.

\cp -rf foo/* bar/

-1

Tanımladığınız işlem bir "birleştirmedir" ve bunu ile yapamazsınız cp. Ancak, birleştirme ve klasörü kaybetmek baristemiyorsanız rm -rf bar, klasörü silebilir ve ardından mv foo baryeniden adlandırabilirsiniz. Her iki işlem de dosya içerikleri tarafından değil, dosya işaretçileri tarafından yapıldığından, bu zaman almaz.


-2

Bunu iki adımdan oluşan komutu kullanmayı deneyin:

rm -rf bar && cp -r foo bar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.