Bagaimana saya bisa menyalin file secara berurutan dengan ekstensi file, menjaga struktur direktori?


71

Pada baris perintah Linux, saya ingin menyalin satu set .txtfile (sangat besar) dari satu direktori (dan subdirektori) ke direktori lain.

Saya perlu struktur direktori untuk tetap utuh, dan saya perlu mengabaikan file kecuali yang berakhiran .txt.


2
Memiliki cp dan temukan sebagai tag di pertanyaan Anda, apakah itu berarti Anda terikat dengan opsi ini? Karena set data Anda sangat besar, masuk akal untuk menganggap proses penyalinan dapat terganggu karena beberapa alasan dan Anda harus memulai ulang. Saya tidak yakin pendekatan find / cp akan dapat melanjutkan transfer dan hanya menyalin bagian yang hilang. Jika Anda tidak terikat untuk menemukan / cp, Anda dapat mempertimbangkan rsync, yang lebih pintar. Opsi --exclude akan memungkinkan Anda untuk melewatkan file .txt.
vtest

Panggilan yang adil - rsync mungkin adalah opsi yang lebih baik. Tidak terikat untuk menemukan / cp. (Saya tetap menggunakannya - rsync tidak diinstal pada mesin jarak jauh, itu adalah server web langsung & saya ingin meninggalkan jejak sekecil mungkin)
bagasi tidak diklaim

Jawaban:


96

Anda dapat menggunakan find dan cpio untuk melakukan ini

cd /top/level/to/copy
find . -name '*.txt' | cpio -pdm /path/to/destdir

(-updm for overwrite destination content.)

kenapa m? Saya pikir itu hanya untuk mempertahankan tanggal modifikasi file.
Mubashar

7
cd /source/path
find -type f -name \*.txt -exec install -D {} /dest/path/{} \;

Anda ketinggalan .setelah find. Juga pada macOS 10.13.1, ini bekerja:find . -type f -name "*.txt" -exec install -v {} /dest/path/{} \;
muram

2

Pendekatan lain

find . -name '*.txt' -exec rsync -R {} path/to/dext \;


Saya suka solusi ini. Saya biasa find . -iname '*.txt' -exec rsync -Rptgon {} path/to/dext \;melakukan pencocokan kasus yang sensitif dan untuk menjaga kepemilikan dan izin.
MountainX

1

Cara termudah yang bekerja untuk saya:

cp --parents -R jobs/**/*.xml ./backup/

satu tangkapan adalah Anda harus menavigasi ke direktori "yang diinginkan" sebelum sehingga "jalur induk" sudah benar.

Pastikan juga Anda mengaktifkan gumpalan rekursif di bash:

shopt -s globstar

1

bagaimana kalau Anda pertama menyalinnya

cp -r /old/folder /new/folder

lalu pergi ke folder baru dan jalankan

find . -type f ! -iname "*.txt" -delete

atau hanya

cp -r /old/folder /new/folder && find . -type f ! -iname "*.txt" -delete

Sunting: ok Anda ingin satu perintah yang menyaring (Saya belum menguji ini karena sistem saya tidak memiliki cpioperintah!). Di sinilah saya menemukannya: http://www.gnu.org/software/findutils/manual/html_mono/find.html#Copying-A-Subset-of-Files

find . -name "*.txt" -print0 |
     cpio -pmd0 /dest-dir

Silakan uji ini dulu, karena saya belum mencobanya. Jika seseorang memverifikasi, itu akan bagus.


mengangguk Ceria - ini akan berhasil, tetapi tanpa memfilter ke .txt Saya melihat beberapa juta file (keluar pada beberapa ratus GB). Jika perlu, saya mungkin harus melakukannya, tetapi saya ingin memfilter sambil menyalin jika mungkin
bagasi tidak diklaim

1
Cheers, versi yang diedit berfungsi jika saya menghapus '0' dari -pmd0
unclaimedbaggage

Anda harus menjaga 0di -pmd0dan menambahkan -print0ke akhir findperintah (sebelum |).
G-Man

1

Saya mencoba melakukan hal yang sama pada macOS, tetapi tidak ada opsi yang bekerja untuk saya. Sampai aku ketemu ditto.

Saya harus menyalin banyak file .wav, dan melewatkannya file Video ... Jadi inilah yang saya buat:

find . -type f -iname "*.wav" -ls -exec ditto {} /destination/folder/{} \;

  • find .- Berjalan menemukan di folder saat ini. pastikan Anda cd /source/foldersebelum memulai

  • -type f - Menentukan hanya mencari file

  • -iname "*.wav" - Ini memberitahukannya untuk mencari case case * .wav yang tidak sensitif
  • -ls- Ini menunjukkan kepada Anda file yang sedang dikerjakannya. Selain itu tidak menunjukkan apa-apa.
  • -exec ditto {} /destination/folder/{} \; - Melakukan semua pekerjaan menyalin dan membuat file dengan pohon direktori yang sama.

0

Arahkan ke direktori:

find . -regex '<regexp_to_get_directories_and_files_you_want>' | xargs -i cp -r --parents {} path/to/destination

Ini sedikit lebih lurus ke depan dan perkasa, jika Anda mengelola ekspresi reguler.


-1

Arahkan ke direktori:

cp '*.css' /path/to/destination

Anda harus menavigasi ke setiap folder di direktori, tetapi ini lebih baik daripada sebagian besar opsi yang saya lihat sejauh ini.


Metode ini tidak rekursif, artinya untuk direktori besar Anda bisa melakukan ini cukup lama ...
Iain Reid
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.