Menyalin file tersembunyi secara rekursif - Linux

19

Apakah ada cara mudah untuk menyalin semua file tersembunyi secara rekursif ke direktori lain? Saya ingin mencadangkan semua file pengaturan di direktori home, bukan file normal. Saya mencoba:

cp -R .* directory

tetapi juga mengenali .dan ..menyalin semua file yang tidak tersembunyi secara rekursif. Apakah ada cara agar cp diabaikan .dan ..?

Zifre
sumber
Apakah ada perbedaan antara -rdan -R?
Chaminda Bandara

Jawaban:

15

Favorit saya untuk memindahkan dir secara umum adalah:

tar cvf - . | (cd /dest/dir; tar xvf -)

yang memecah direktori saat ini ke stdout kemudian pipa ke subshell yang pertama cd ke direktori tujuan sebelum menghapus stdin. Sederhana, langsung, dapat diperpanjang - pertimbangkan apa yang terjadi ketika Anda mengganti () dengan ssh ke komputer lain. Atau untuk menjawab pertanyaan Anda, Anda mungkin melakukan:

tar cvf - .* --exclude=\. --exclude=\.\. | (cd /dest/dir; tar xvf -)
pjz
sumber
1
Terima kasih, opsi pengecualian adalah yang saya butuhkan. Saya sudah melakukannya dengan cara lain, tetapi saya akan menyimpan ini untuk referensi di masa mendatang. Ini tampaknya sangat fleksibel (walaupun mungkin lebih lambat).
Zifre
1
Saran yang bagus. Saya memiliki beberapa perbaikan: 1) Gunakan cd /dest/dir && tar xvf -. Ini &&akan menghentikan Anda dari menabrak direktori sumber jika Anda memiliki kesalahan ketik di tujuan. 2) Anda hanya perlu vflag tar pada salah satu perintah tar (atau tidak).
Tom Shaw
Cukup adil. Saya juga diketahui mengelompokkan hal-hal dengan cara lain: menyalin srcdir jarak jauh ke sini, do(cd /src/dir && tar cf - .) | tar xvf -
pjz
17

Hampir setiap kali ini bisa diselesaikan hanya dengan:

cp -R .[a-zA-Z0-9]* directory

Sangat tidak biasa memiliki file tersembunyi yang tidak dimulai dengan salah satu karakter tersebut.

Pencocokan pola lain tersedia ( .??*, .[^.]*) - lihat komentar

Alnitak
sumber
Itu hanya akan mengabaikan.-Xyz - hal-hal di [] hanya cocok dengan karakter pertama setelah titik.
Hamish Downer
6
. [^.] * akan menangkap segalanya
falstro
1
... kecuali hal-hal yang dimulai dengan dua periode.
falstro
@roe - itu versi yang bagus juga
Alnitak
@mish - ya, saya memang mengatakan banyak jawabannya.
Alnitak
11

Anda bisa menggunakannya rsync.

rsync -a ./ /some/other/directory/

yang akan menyalin isi direktori saat ini (termasuk file dot, tetapi tidak termasuk ..)

Rory
sumber
Sederhana, dan berfungsi untuk file tersembunyi di folder tersembunyi juga.
user59183
bagi saya ini adalah solusi yang kurang membingungkan dan paling efektif yang diberikan
palerdot
Solusi yang bagus. Saya juga membutuhkannya untuk tidak menyalin di .gitdir. Menambahkan -C melakukan ini dan perintahnya menjadi:rsync -aC ./ /some/other/directory/
ada
10

Saya mohon Anda, menjauhlah dari ekspansi shell biasa pada cpbaris perintah - ekspansi shell memiliki segala macam kasus sudut "menarik" ahem (rekursi yang tidak diinginkan yang disebabkan oleh. Dan .., spasi, hal-hal yang tidak dapat dicetak, hardlink, tautan simbolik, dan seterusnya.) Gunakan findsaja (ini ada dalam findutilspaket, jika Anda belum menginstalnya - yang akan aneh, semua distribusi menginstalnya secara default):

find -H /path/to/toplevel/dir/ -maxdepth 1 -name '.*' -a \( -type d -o -type f -o -type l \) -exec cp -a '{}' /path/to/destination/dir/ \;

Penjelasan langkah demi langkah:

  • -Hakan menyebabkan findtidak mengikuti symlinks (kecuali jika nama direktori toplevel sebenarnya yang Anda berikan adalah symlink; itu akan mengikuti.)
  • /path/to/toplevel/dir/ Jelas, seharusnya diganti oleh Anda dengan path melakukan direktori yang menampung file pengaturan dan direktori yang ingin Anda buat cadangannya.
  • -maxdepth 1akan berhenti finddari turun secara rekursif ke direktori mana pun yang namanya dimulai dengan titik. Kita tidak perlu mengulanginya, cpakan melakukan itu untuk kita, kita hanya perlu nama-nama di tingkat ini.
  • -name '.*'memberitahu findkita bahwa kita ingin semua nama yang dimulai dengan titik. Ini tidak akan berfungsi dengan benar jika variabel lingkungan POSIXLY_CORRECTdiatur, tetapi jarang (jika pernah). Ini adalah kondisi pertandingan pertama yang kami tentukan sejauh ini.
  • a \( ....... \)adalah dan diikuti oleh kondisi yang lebih kompleks di dalam tanda kurung (saya telah menggunakan ..... untuk menggantinya, dijelaskan di bawah ini.) Kita perlu melarikan diri dari tanda kurung karena kalau tidak mereka akan (salah) ditafsirkan oleh shell, maka garis miring terbalik di depan mereka,
  • -type d -o -type f -o -type ltiga kondisi dengan atau di antara mereka. -type dcocok dengan direktori, -type fcocok dengan file biasa, dan -type lcocok dengan symlink. Anda dapat memilih apa yang Anda inginkan - misalnya, jika Anda tidak ingin membuat cadangan direktori pengaturan, hilangkan -type d(dan -otepat di belakangnya, jelas.)
  • -exec ..... \;memberitahu finduntuk mengeksekusi perintah setiap kali kecocokan ditemukan. Akhir dari perintah ditandai dengan tanda titik koma, yang lagi-lagi kita perlu melarikan diri dengan backslash untuk menghindari interpretasi shell. Di dalam baris perintah itu, Anda harus menggunakan di {}mana Anda ingin nama kecocokan yang saat ini ditemui berakhir. Karena kerang mungkin juga salah menafsirkan kurung kurawal, Anda harus meletakkannya di apostrof, seperti pada '{}'. Perintah yang ingin kita jalankan dalam kasus ini adalah cp -a '{}' /path/to/destination/dir/(-a berarti arsip, yang berulang dalam subdirektori, menyalin symlink sebagai tautan, dan mempertahankan izin dan atribut yang diperluas, dan /path/to/destination/dir/jelas merupakan nama direktori tujuan - ganti itu.)

Jadi, dalam bahasa Inggris yang sederhana, findbaris perintah ini mengatakan ini:

Mulai dari / path / ke / tingkat atas / dir /. Jangan turun ke subdirektori mana pun. Temukan semua direktori, file, dan symlink yang namanya dimulai dengan titik. Untuk setiap yang Anda temukan ditemukan, salin ke / path / ke / tujuan / dir / melestarikan alam, izin, dan atribut yang diperluas.

Mihai Limbăşan
sumber
1
temukan adalah hal yang paling berguna yang pernah ada.
Mr. Shiny dan New New 宇
1
Jawaban bagus. Meskipun saya lebih suka -exec ... ';' Menghindari backslash berarti perintah ini akan bekerja baik dalam CLI dan di crontab :))
kubanczyk
8

Saya selalu menggunakan. ?? * untuk menemukan file tersembunyi tanpa mendapatkan "." dan "..". Mungkin melewatkan ".a" atau sesuatu, tetapi saya tidak pernah memilikinya.

Paul Tomblin
sumber
pasti bagus dan rapi :) +1
falstro
Saya tidak ingin misterius gagal jika ada beberapa ".a" s
Zifre
Saya suka karena jika Anda tahu Anda tidak memiliki file tersembunyi karakter tunggal, sangat cepat untuk mengetik.
Paul Tomblin
Ini harus menjadi jawaban terbaik. Itu harus diunggulkan ke atas.
Ibn Saeed