Saya mencoba menjalankan perintah yang mirip dengan yang di bawah ini dalam skrip bash. Itu harus mencari melalui semua subfolder $sourcedir
dan menyalin semua file dari jenis tertentu ke tingkat root $targetdir
.
#!/bin/bash
# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;
Hal ini tampaknya menjadi cukup dekat, kecuali bahwa {}
tidak sedang dilewatkan sebagai $2
untuk-exec sh -c ...
Saya ingin melakukan ini sedekat mungkin dengan "jalan yang benar", dengan toleransi untuk karakter khusus dalam nama file (khususnya karakter kutipan tunggal).
Sunting: Saya melihat orang-orang menyarankan menggunakan xargs
atau chaining argumen. Saya mendapat kesan bahwa ini hanya ok untuk sejumlah argumen. Jika saya memiliki, misalnya, ribuan file .jpg yang saya coba salin dari sejumlah direktori galeri ke direktori rangkai salindia raksasa, akankah solusi chaining argumen masih berfungsi?
Sunting 2: Masalah saya adalah saya tidak memiliki _
sebelum opsi pertama saya untuk sh dalam -exec
perintah. Bagi siapa saja yang ingin tahu tentang cara membuat perintah find berfungsi, tambahkan _
dan semuanya akan baik-baik saja:
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" "$targetdir" \;
Saya telah menerima jawaban di bawah ini karena itu menyelesaikan tugas yang sama, tetapi lebih efisien dan elegan.
sumber
xargs
pernah dibuat, untuk secara otomatis menangani sejumlah besar argumen pada perintah reguler yang memiliki batas. Juga untuk mempertimbangkan, sebagian besar batasan argumen maks, telah jauh ditingkatkan untuk utilitas GNU standar. Anda juga akan melihat manfaat kinerja, menghindari semua proses garpu, yang pada ribuan file relevan.Jawaban:
Anda ingin menyalin file dari tipe tertentu, ke direktori tertentu? Ini paling baik dilakukan
xargs
, dan Anda bahkan tidak membutuhkannyash
. Ini adalah cara yang lebih tepat untuk melakukannya, juga harus berjalan lebih efisien.Jika Anda perlu menangani nama file khusus, maka gunakan
NULL
sebagai pemisah Andasumber
-print0
kefind
dan-0
kexargs
NULL
tidak perlu jika Anda menggunakan'{}'
, itu penting ketika Anda tidak menggunakannya. Manfaat nyata antara yang lain, selainPOSIX
kepatuhan, adalah kinerja.Anda harus memberikan
{}
argumen ke shell lalu lewati setiap argumen.Catatan : Cara kerjanya adalah arg pertama ke shell adalah nama shell , kita dapat mengeksploitasi ini dengan meneruskan nama sebagai
$targetdir
dan kemudian menggunakan parameter khusus$0
di dalam skrip shell untuk mengakses targetdir itu.sumber
"$targetdir"
tidak diperluas di dalam tanda kutip tunggal.Jika Anda tidak percaya pada gereja xargs:
Penjelasan:
salinan b, c dan d ke target ar a.
menjalankan perintah pada banyak file sekaligus, bukan satu demi satu (yang standar, jika Anda gunakan
";"
bukan+
). Inilah sebabnya mengapa harus menarik targetdir ke depan dan menandainya secara eksplisit sebagai target.Ini berfungsi untuk gnu-find dan mungkin tidak untuk implementasi find lainnya. Tentu saja ini bergantung pada -t-flag juga.
TechZilla tentu saja sejauh ini, benar
sh
tidak diperlukan untuk memanggil cp.Jika Anda tidak menggunakan
xargs
, yang sebagian besar tidak perlu dikombinasikan denganfind
, Anda diselamatkan dari mempelajari-print0
dan-0
menandai.sumber
xargs
. Contoh terbesar, bagaimana jika Anda tidak menemukan file? Saya menggunakan xargs sebagai gantifor
loop umum sepanjang waktu,find
cakupannya jauh lebih kecil. Selain itu,find
hanya mendukung bahwa+
jika Anda menggunakan GNUfind
, itu tidak didefinisikan dalam POSIX. Jadi, sementara Anda harus merasa bebas untuk memilihfind
sendiri, itu tidak melakukan semua yang dilakukan xargs. Ketika Anda mempertimbangkan GNU,xargs
Anda juga akan mendapatkan-P
yang multi-core. Bagaimanapun juga, itu layak dipelajarixargs
.sumber