Bagaimana saya bisa menyalin file dan membuat direktori target secara bersamaan?

20

Saya ingin cp aaa/deep/sea/blob.psdkebbb/deep/sea/blob.psd

Bagaimana cara saya menyalin jika direktori deepdan seatidak ada di bawah bbbsehingga salinan keduanya membuat direktori yang diperlukan dan menyalin file?

Saat ini saya
No such file or directorymenjadi sedalam dan laut tidak ada.

Saya melihat-lihat halaman bantuan pria dan pertanyaan-pertanyaan lain tetapi tidak ada yang muncul pada saya.

Yang paling dekat saya gunakan rcpuntuk direktori:

rcp -r aaa/deep/sea/ bbb/deep/sea/

meskipun ini menyalin seluruh direktori dan isinya dan saya hanya ingin satu file. Namun mencoba untuk melakukan itu membericp: cannot create regular file bbb/deep/sea/blob.psd' such file or directory

Michael Durrant
sumber

Jawaban:

19

Coba gunakan fungsi selanjutnya untuk situasi seperti itu:

copy_wdir() { mkdir -p -- "$(dirname -- "$2")" && cp -- "$1" "$2" ; }

dan gunakan sebagai

copy_wdir aaa/deep/sea/blob.psd bbb/deep/sea/blob.psd

Omong-omong, GNU cpmemiliki --parentsopsi. Ini sangat dekat dengan apa yang Anda inginkan, tetapi tidak persis.
Itu juga akan membuat aaadirektori yang sepertinya Anda tidak perlu. Namun Anda pertama-tama dapat aaamenyalin dan menyalin seperti:

cd aaa && cp --parents deep/sea/blob.psd ../bbb/
buru-buru
sumber
24

Sangat mudah menggunakan installprogram dari coreutils yang biasanya digunakan untuk tujuan ini dengan membangun sistem seperti automake :

install -D /path/to/source /path/to/destination

Catatan yang installmembuat semua bagian jalan seperti mkdir -phalnya, lihat man install. Saya ingin tahu mengapa Anda tidak menyertakan mengapa Anda ingin melakukan itu. Memanggil mkdirdan cpsangat mudah.

Pavel Šimerda
sumber
2
Saya pikir ada banyak jawaban bagus untuk pertanyaan ini, tetapi jawaban ini mendapat suara saya karena ini yang paling portabel. The rsyncjawabannya hanya akan membuat 1 direktori, dan paxtampaknya tidak menjadi umum.
Patrick
Gunakan -dsebagai ganti -Dpada Mac.
Matt M.
perhatikan bahwa perintah ini membuat file tujuan dengan 755( rwxr-xr-x) izin, yang mungkin tidak diinginkan. Anda dapat menentukan sesuatu yang lain dengan -msakelar, tetapi saya tidak dapat menemukan cara untuk hanya menyimpan izin file :(
törzsmókus
6

Dengan perintah standar (POSIX / Unix), Anda dapat:

pax -rws ':^:dest/dir/:' file .
Stéphane Chazelas
sumber
1
Menarik. Saya belum pernah mendengar pax sebelumnya. Padahal saya suka konsepnya. Sayangnya meskipun dalam POSIX, sepertinya sangat sedikit distro yang menginstalnya secara default :-(
Patrick
@ Patrick - jika Anda melewati semua jalan sampai akhir info tar- di suatu tempat di sekitar bagian portabilitas - saya pikir Anda akan menemukan bahwa GNU tarmengklaim sepenuhnya paxkompatibel. Saya tetap melakukannya, meskipun saya belum pernah mencoba menguji klaim itu.
mikeserv
5

Saya tidak mengetahui cara melakukannya menggunakan cp, tetapi tentu saja mungkin menggunakan rsync:

$ rsync sourcefile dir/

di mana dirdirektori yang tidak harus ada. Ada banyak cara lain untuk mencapai hal yang sama menggunakan perintah lain.

mjturner
sumber
3
Anda perlu rsync -Rmempertahankan hierarki direktori
glenn jackman
@glennjackman Memang, penggunaan yang 'layak' rsyncmembutuhkan lebih banyak opsi, tetapi pertanyaannya adalah tentang membuat direktori target yang tidak ada, maka jawaban singkat saya :)
mjturner
1
Setidaknya GNU cpmemiliki --parentsopsi.
peterph
2
@peterph Memang, tapi kemudian Anda dibatasi dalam penamaan direktori target
mjturner
4
cd aaa
pax -rw deep/sea/blob.psd ../bbb

Jika Anda tidak memiliki pax(itu diamanatkan oleh POSIX, sebagai pengganti standar cpio dan tar yang memiliki terlalu banyak ketidakcocokan untuk distandarisasi), gunakan cpio -patau tar -cf - … | tar -xf -sebagai gantinya.

Gilles 'SANGAT berhenti menjadi jahat'
sumber