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.