Memindahkan jutaan file ke direktori berbeda dengan pola nama khusus


10

Saya memiliki jutaan file dengan nomenklatur berikut di mesin Linux:

1559704165_a1ac6f55fef555ee.jpg

10 digit pertama adalah cap waktu dan yang diikuti oleh _adalah id khusus. Saya ingin memindahkan semua file yang cocok dengan id nama file tertentu ke folder yang berbeda.

Saya mencoba ini pada direktori dengan file

find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"

Namun saya mendapatkan kesalahan yang menunjukkan:

bash 1559704165_a1ac6f55fef555ee.jpg: command not found

Ketika saya mencoba, mv ??????????_a1ac*.jpg saya mendapatkan daftar argumen kesalahan terlalu lama. Saya memiliki minimal 15 pola nama file yang berbeda. Bagaimana cara memindahkan mereka.


1
Si bash mengatakan itu semua: ia mencoba mengeksekusi nama file itu karena itu adalah yang pertama pada baris di tahap ke-2 pipa (pipa tahap ke-2 Anda adalah | ??????????_a1ac*.jpg:: bash memperluasnya ke beberapa nama file, yang pertama 1559704165_a1ac6f55fef555ee.jpg, saat Anda berakhir , pada tahap ke-2 pipa itu, mencoba mengeksekusi: 1559704165_a1ac6f55fef555ee.jpg next_matching_filename 3rd_matching_filename ... nth_matching_filenameSaya kira Anda malah mencoba memfilter ke nama file itu (lihat jawaban di bawah untuk itu)
— Olivier Dulac

Jawaban:


15

Kamu harus menggunakan:

find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' \
-exec mv -t destination "{}" +

Jadi maxdepth 1artinya Anda ingin mencari di direktori saat ini tanpa subdirektori.

type f berarti hanya menemukan file.

name '??????????_a1ac*.jpg' adalah pola yang cocok dengan file yang Anda cari.

mv -t destination "{}" +berarti memindahkan file yang cocok ke tujuan. Di sini +menambahkan file-file baru yang cocok ke yang sebelumnya seperti:

mv -t dest a b c d

Di sini abcd adalah file yang berbeda.


Terima kasih telah menjawab pertanyaan orang ini dengan singkat. Daripada hanya membuang solusi, mungkin Anda bisa menjelaskan bagaimana / apa / mengapa. Alih-alih berguna bagi satu orang, satu kali, ini dapat bermanfaat bagi semua orang, setiap saat. Pertanyaan yang sama telah ditanyakan & dijawab berkali-kali selama 40-50 tahun terakhir. Masalahnya, tidak pernah dijelaskan dengan baik. Ajari manusia memancing .. Sementara itu: gnu.org/software/findutils/manual/html_node/find_html/… dan seperti yang sering terjadi, Wikipedia lebih bermanfaat daripada dokumen resmi: en.wikipedia.org/wiki/Find_ ( Unix)
— suara

Lihat jawaban yang diperbarui.
— Prvt_Yadav

Perhatikan bahwa itu -tadalah ekstensi GNU dan mungkin tidak tersedia pada jenis turunan UNIX lainnya.
— Kevin

Ketika Anda mengatakan "Kutipan ganda mencegah pemisahan kata." Saya kira Anda merujuk "{}", dalam hal ini saya ingin menunjukkan bahwa {}tidak diperluas oleh shell dan tidak perlu dikutip. Shell melewati {}untuk menemukan, dan menemukan melihat {}dan menggantinya dengan nama path. Find exec tidak menggunakan parser shell dan tidak melakukan pemisahan kata sendiri. Mengutip itu tidak membahayakan, hanya saja justifikasi yang diberikan sedikit tidak akurat.
— jw013

@ jw013 terima kasih.
— Prvt_Yadav

11

Perintahmu,

find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"

Pipa daftar semua file KE semua file!

find . -maxdepth 1 -type f -name `*_a1ac*.jpg` -print0 |\
xargs  -0 -r mv -t "/home/ubuntu/ntest"

akan melakukan trik.


1
terima kasih banyak ... solusi Anda berhasil juga ... terima kasih telah memberi tahu saya di mana kesalahan saya
— Apricot

8

Anda sangat dekat. Anda harus menggunakan -nameopsi untuk find. Dan ingatlah untuk mengutip polanya.

Begitu

find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' |xargs mv -t "/home/ubuntu/ntest"

Terima kasih banyak ... solusi Anda berhasil juga .... tambahan terima kasih telah memberi tahu saya bahwa saya sudah dekat dengan solusi .... ini adalah motivator bagi pemula seperti saya
— Apricot

1
Anda harus menambahkan -print0sebagai argumen terakhir ke find (bukan default: -print), dan menambahkan a -0sebagai opsi pertama ke xargs (yaitu:) xargs -0 mv -t "/home/ubuntu/ntest". dengan cara itu, semua jenis nama file aneh (dengan spasi di dalamnya, dengan "baris baru" di dalamnya, dll) dapat ditangani. find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' -print0 |xargs -0 mv -t "/home/ubuntu/ntest" (hanya bekerja dengan find mirip GNU)
— Olivier Dulac

2

Tidak sebagus findsolusi, tetapi solusi lain yang valid adalah membuat mvperintah lebih terperinci.

Ini tidak 4096 bergerak, dengan lebih sedikit jumlah file dipindahkan per mvoperasi.

FILEPAT=a1ac
for i in $(seq $((0x000)) $((0xfff))); 
do 
   H=$(printf '%x\n' $i)
   mv 1559704165_${FILEPAT}${H}*.jpg /home/ubuntu/ntest
done

Ini adalah retasan cerdas untuk mereka yang tidak find(karena alasan apa pun).
— hutan

-1

Jika Anda ingin memindahkan file pada sistem host yang sama, yang saya kira Anda lakukan dengan Anda mv, rsyncbisa menjadi pilihan yang lebih cepat:

rsync -av --inplace -W /source/??????????_a1ac*.jpg /home/ubuntu/ntest/

--inplacedan -Wdiatur untuk mempercepat proses.

Jika ini menghasilkan daftar argumen lain yang terlalu panjang maka Anda bisa memberi makan daftarrsync

Buat daftar dengan find, misalnya

find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txt

dan berikan kepada rsync

rsync -av --inplace -W --files-from=/tmp/my_image_list.txt /path/to/files /home/ubuntu/ntest/

Sumbernya di sini adalah /path/to/files, karena rsyncakan memperlakukan daftar yang Anda berikan sebagai relatif terhadap sumber Anda.


Intinya adalah: rsynclebih cepat daripada mv, jika file tidak pada sistem file yang sama .


Ini kemungkinan akan mengenai kesalahan "daftar argumen terlalu lama" yang sama dengan yang disebutkan OP
— Grump

@ Grump, untuk menghindari ini, OP dapat menulis daftar file yang akan disalin ke file, yaitu find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txtdan kemudian meneruskannya ke rsync dengan --files-from=/tmp/my_image_list.txt. Intinya rsyncadalah lebih cepat. Kecuali jika file-file tersebut berada pada sistem file yang sama, yang belum ditunjukkan OP.
— Robert Riedl

@RobertRiedl: Anda harus mengedit jawaban Anda dan menambahkan informasi ini. Komentar dapat tidak kekal.
— NickD

@NickD, saya sudah memperbarui jawaban saya.
— Robert Riedl
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.