Linux cara menyalin tetapi tidak menimpa?

386

Saya ingin cpdirektori tetapi saya tidak ingin menimpa file yang ada bahkan itu lebih tua dari file yang disalin. Dan saya ingin melakukannya sepenuhnya non-aktif karena ini akan menjadi bagian dari skrip Crontab Bash. Ada ide?

mnowotka
sumber

Jawaban:

589

Diambil dari halaman manual :

-n, --no-clobber
              do not overwrite an existing file (overrides a previous -i option)

Contoh:

cp -n myoldfile.txt mycopiedfile.txt
hovanessyan
sumber
33
Catatan, ini akan keluar dengan kesalahan jika file tersebut ada. Untuk keluar dengan sukses, coba cp -n source.txt destination.txt || true
galenandrew
13
@galenandrew cp -ntidak keluar dengan kesalahan jika file ada di Ubuntu 12.04.
amit
@galenandrew Dikonfirmasi. Terima kasih. Proyek saya tidak membangun di Xcode setelah menambahkan skrip run ke target saya.
Ruiz
@ AaronFranke seperti itu.
Boris
93

Pertimbangkan untuk menggunakan rsync.

rsync -a -v --ignore-existing src dst

Per komentar rsync -a -v src dsttidak benar karena akan memperbarui file yang ada.

Hans Ginzel
sumber
7
Anda ingin menambahkan --ignore-existingtanda untuk mencegah file yang ada ditimpa.
Semua Pekerja Sangat Penting
7
Perintah lengkap rsync -a -v --ignore-existing <src> <dst>memang jawaban yang benar, bukan di cp -uatas.
Whitebird
Jika salinan sebelumnya terputus dan hanya file terpotong yang disalin, saya yakin cp -u tidak akan menyalinnya lagi ... tetapi akankah rsync, dengan --ignore-existing? Mungkin juga tidak ... jadi itu membuat mereka benar-benar setara, bukan?
dagelf
rsync menyimpan stempel waktu file sementara cp menggunakan waktu saat ini (menurut pengalaman saya)
Stefan Diabo
1
beberapa server tidak memiliki rsync
mebada
51
cp -n

Apa yang kamu inginkan. Lihat halaman manual.

pembual
sumber
@ AaronFranke ya, itu akan bekerja secara rekursif.
Boris
33

Ini akan bekerja pada RedHat:

false | cp -i source destination 2>/dev/null

Memperbarui dan tidak menimpa adalah sesuatu yang berbeda.

ceving
sumber
4
Apa yang falsedilakukan di sini?
Api Beku
11
@FrozenFlame Menjawab -ipertanyaan.
ceving
Jelas, perintah ini tidak akan berfungsi jika Anda akan mencoba menyalin lebih dari file ARG_MAX. Untuk mengatasi masalah ini, periksa tautan ini .
mginius
2
Juga jelas, perintah ini tidak akan berhasil jika bumi menabrak matahari.
ceving
32

Untuk orang yang menemukan bahwa tidak memiliki opsi 'n' (seperti saya di RedHat) dapat Anda gunakan cp -u hanya menulis file jika sumbernya lebih baru dari yang ada (atau tidak ada yang ada).

Seperti yang disebutkan dalam komentar, ini akan menimpa file yang lebih lama, jadi bukan yang diinginkan OP. Gunakan jawaban ceving untuk itu.

Suram...
sumber
11
OP diminta untuk tidak menimpa file yang sudah ada meskipun lebih tua dari file yang disalin , jadi -utidak benar-benar sesuai dengan tujuan.
Andrew Lott
4
Astaga, Anda memang benar. Saya terkejut butuh waktu lama bagi siapa pun untuk memperhatikan.
Suram ...
Mungkin bukan itu yang diminta OP, tapi itulah tepatnya yang saya butuhkan untuk Uberspace saya (Centos 7). Terima kasih!
Thomas Praxl
Saya senang enam tahun lalu saya bisa membantu :-D
Grim ...
10

Alpine linux: Jawaban di bawah ini hanya untuk kasus file tunggal: di alpine cp -ntidak berfungsi (dan false | cp -i ...juga) jadi solusi yang berfungsi dalam kasus saya yang saya temukan adalah:

if [ ! -f env.js ]; then cp env.example.js env.js; fi 

Dalam contoh di atas jika env.jsberkas tidak ada maka kita copy env.example.jske env.js.

Kamil Kiełczewski
sumber
1

Beberapa versi cp tidak memiliki opsi --no-clobber . Dalam hal itu:

  echo n | cp -vipr src/* dst
Oktavianus
sumber