Saya ingin tahu persis apa {} \;
dan {} \+
dan apa yang | xargs ...
dilakukan. Harap klarifikasi ini dengan penjelasan.
Di bawah 3 perintah dijalankan dan menghasilkan hasil yang sama tetapi perintah pertama membutuhkan sedikit waktu dan formatnya juga sedikit berbeda.
find . -type f -exec file {} \;
find . -type f -exec file {} \+
find . -type f | xargs file
Itu karena yang pertama menjalankan file
perintah untuk setiap file yang berasal dari find
perintah. Jadi, pada dasarnya ini berjalan sebagai:
file file1.txt
file file2.txt
Tetapi yang terakhir 2 temukan dengan -exec
perintah jalankan perintah file sekali untuk semua file seperti di bawah ini:
file file1.txt file2.txt
Kemudian saya menjalankan perintah berikut di mana yang pertama berjalan tanpa masalah tetapi yang kedua memberikan pesan kesalahan.
find . -type f -iname '*.cpp' -exec mv {} ./test/ \;
find . -type f -iname '*.cpp' -exec mv {} ./test/ \+ #gives error:find: missing argument to `-exec'
Untuk perintah dengan {} \+
, itu memberi saya pesan kesalahan
find: missing argument to `-exec'
mengapa demikian? Adakah yang bisa menjelaskan apa yang saya lakukan salah?
Jawaban:
The halaman pengguna (atau secara online pengguna GNU ) cukup banyak menjelaskan semuanya.
temukan perintah -exec {} \;
Untuk setiap hasil,
command {}
dieksekusi. Semua kemunculan{}
diganti dengan nama file.;
diawali dengan garis miring untuk mencegah shell menafsirkannya.temukan -exec perintah {} +
Setiap hasil ditambahkan
command
dan dieksekusi sesudahnya. Dengan mempertimbangkan batasan panjang perintah, saya rasa perintah ini dapat dieksekusi lebih banyak, dengan halaman manual mendukung saya:Perhatikan kutipan ini dari halaman manual:
Itulah mengapa tidak ada karakter yang diperbolehkan di antara
{}
dan+
kecuali spasi.+
membuat find mendeteksi bahwa argumen harus ditambahkan ke perintah sepertixargs
.Solusinya
Untungnya, implementasi GNU
mv
dapat menerima direktori target sebagai argumen, dengan salah satu-t
atau parameter yang lebih panjang--target
. Penggunaannya adalah:find
Perintah Anda menjadi:Dari halaman manual:
sumber
./test/
antara{}
dan+
, tetapi tidak ada karakter non-spasi kosong yang diperbolehkan di antara keduanya.+
perintah adalah AFAIU aneh sedikit karena tongkat file pada "akhir" (dan bukan di tempat{}
) jadi mengapa menggunakan{}
sama sekali - ini membingungkan. Terima kasih atas-t
opsi yang tidak saya ketahui, tampaknya opsi itu dibuat sebagai solusi untuk-exec +
masalah itu!Saya mengalami masalah yang sama di Mac OSX , menggunakan shell ZSH : dalam hal ini tidak ada
-t
opsi untukmv
, jadi saya harus mencari solusi lain. Namun perintah berikut berhasil:Rahasianya adalah mengutip kawat gigi . Tidak perlu kawat gigi berada di akhir
exec
perintah.Saya menguji di bawah Ubuntu 14.04 (dengan shell BASH dan ZSH ), itu berfungsi sama.
Namun, saat menggunakan
+
tanda tersebut, tampaknya memang harus berada di akhirexec
perintah.sumber
{}
kebutuhan akan dikutip dalamfish
danrc
kerang, tetapi tidak dalamzsh
,bash
maupun kerang lain dari Bourne atau keluarga csh.bash
, memang tanda kutipnya tidak perlu. Anehnya, saya mengalami masalah jika tidak mengutipnya di bawah MacOS (menggunakanzsh
). Tapi saya tidak memiliki Mac yang bisa dijangkau untuk mencoba lagi ...Persamaan standar
find -iname ... -exec mv -t dest {} +
untukfind
implementasi yang tidak mendukung-iname
ataumv
implementasi yang tidak mendukung-t
adalah menggunakan shell untuk menyusun ulang argumen:Dengan menggunakan
-name '*.[cC][pP][pP]'
, kami juga menghindari ketergantungan pada lokal saat ini untuk memutuskan apa versi huruf besarc
ataup
.Perhatikan bahwa
+
, berlawanan dengan;
is not special di shell manapun jadi tidak perlu dikutip (meskipun mengutip tidak akan merugikan, kecuali tentu saja dengan shell sepertirc
itu tidak mendukung\
sebagai operator kutipan).Trailing
/
di/dest/dir/
adalah agarmv
gagal dengan kesalahan bukan mengubah namafoo.cpp
untuk/dest/dir
dalam kasus di mana hanya satucpp
file yang ditemukan dan/dest/dir
tidak ada atau tidak direktori (atau symlink ke direktori).sumber
sumber
tidak, perbedaan antara
+
dan\;
harus dibalik.+
menambahkan file ke akhir perintah exec kemudian menjalankan perintah exec dan\;
menjalankan perintah untuk setiap file.Masalah yaitu
find . -type f -iname '*.cpp' -exec mv {} ./test/ \+
harusfind . -type f -iname '*.cpp' -exec mv {} ./test/ +
ada kebutuhan untuk melarikan diri atau mengakhiri+
xargs Saya sudah lama tidak menggunakannya tapi menurut saya berfungsi seperti +.
sumber
-name "*.cpp"
Saya hampir tidak menggunakan -iname kecuali jika saya ingin melakukan pencarian regex yang sulit, seperti -iname '??? work. * \. Cpp'-iname
dan-name
.-iname
adalah versi peka huruf besar / kecil-name
dan tidak memiliki perbedaan dalam penanganan ekspresi reguler. Saya sarankan untuk mencoba perintah sebelum memposting, perintah Anda gagal di shell saya juga.