Saya mencoba menjalankan perintah berikut:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' +
Ini mengembalikan kesalahan:
find: missing argument to -exec
Saya tidak dapat melihat apa yang salah dengan perintah ini, karena sepertinya cocok dengan halaman manual:
perintah -exec {} +
Varian opsi -exec ini menjalankan perintah yang ditentukan pada file yang dipilih, tetapi baris perintah dibangun dengan menambahkan setiap nama file yang dipilih di akhir; jumlah undangan perintah akan jauh lebih sedikit daripada jumlah file yang cocok. Baris perintah dibangun dengan cara yang sama seperti xargs membangun baris perintahnya. Hanya satu instance dari '{}' diizinkan dalam perintah. Perintah dijalankan di direktori awal.
Saya juga mencoba:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' {} +
find a/folder b/folder -name *.c -o -name *.h -exec 'grep -I foobar' '{}' +
find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar '{}' +
find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar '{}' +
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
+
pada akhirnya?find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
find
. Meskipun-exec cmd {} +
variannya adalah POSIX dan telah tersedia sejak tahun 80-an, GNU menemukan hanya menambahkannya (relatif) baru-baru ini (2005). Apa yangfind --version
memberitahu Anda?-exec {} +
ditambahkan pada 4.2.12 pada 2005. Dalam penemuan GNU yang lebih lama, Anda dapat menggunakan (non-POSIX)-print0 | xargs -r0
untuk mendapatkan yang serupa.4.1
berasal dari 1994.-name
argumen pola harus dikutip:-name "*.c" -o -name "*.h"
. Ini benar, meskipun itu tidak terkait dengan-exec
kesalahan. Anda akan melihat bahwa semua jawaban lain memasukkan tanda kutip ke dalam tanda kutip, meskipun hanya Gilles yang menyebutkannya. … (Lanjutan)-name "*.[ch]"
tanpa penjelasan. Ini memiliki manfaat menyederhanakan baris perintah dan, khususnya, menghilangkan-o
. Menemukan ekspresi yang melibatkan-o
sulit untuk diperbaiki. Anda salah; jika perintah Anda diperbaiki sehingga tidak salah (seperti dalam jawaban Gilles), itugrep
hanya akan berjalan pada.h
file. Yang perlu Anda lakukan'(' -name '*.c' -o -name '*.h' ')'
.Jawaban:
Anda perlu menghapus tanda kutip tunggal yang Anda gunakan di sekitar
{}
. Perintah dapat disederhanakan seperti ini:Jika Anda menggunakan versi menemukan GNU kuno, ini harus tetap berfungsi:
sumber
{}
tidak memiliki arti khusus untuk shell."Argumen yang hilang
-exec
" biasanya berarti bahwa argumen untuk -exec
tidak ada terminatornya. Terminator harus berupa argumen yang hanya berisi karakter;
(yang perlu dikutip dalam perintah shell, jadi biasanya ditulis\;
atau';'
), atau dua argumen berturut-turut yang mengandung{}
dan+
.Stephane Chazelas telah mengidentifikasi bahwa Anda menggunakan versi GNU yang lebih lama yang tidak
-exec … {} +
hanya mendukung-exec {} \;
. Meskipun GNU adalah pengadopsi akhir-exec … {} +
, saya merekomendasikan Anda untuk mendapatkan tool suite yang kurang antik (seperti Cygwin , yang mencakup git dan banyak lagi, atau GNUwin32 , yang tidak memiliki git tetapi tidak memiliki karyawan yang mencoba-buruk -untuk menggunakan-linux-but-we-impose-windows vibe yang diberikan Cygwin). Fitur ini ditambahkan dalam versi 4.2.12, lebih dari 9 tahun yang lalu (itu adalah fitur terakhir yang diidentifikasi untuk membuat GNUfind
POSIX-compliant).Jika Anda ingin tetap menggunakan GNU yang lebih lama, Anda dapat menggunakannya
-print0
denganxargs -0
untuk mendapatkan fungsionalitas yang serupa: eksekusi perintah yang dikelompokkan, mendukung nama file yang sewenang-wenang.Selalu kutip wildcard di
find
baris perintah. Jika tidak, jika Anda menjalankan perintah ini dari direktori yang berisi.c
file, tanda kutip*.c
akan diperluas ke daftar.c
file di direktori saat ini.Menambahkan
/dev/null
kegrep
baris perintah adalah trik untuk memastikan bahwa grep akan selalu mencetak nama file, bahkan jikafind
kebetulan menemukan kecocokan tunggal. Dengan GNU find, metode lain adalah dengan melewatkan opsi-H
.sumber
Jika perintah seperti
mengembalikan kesalahan
kemungkinan penyebabnya adalah GNU
find
yang terlalu lama yang tidak mendukung sintaksis-exec mycommand {} +
. Dalam hal ini penggantian kinerja rendah adalah menjalankan-exec mycommand {} \;
yang akan berjalanmycommand
sekali untuk setiap target yang ditemukan alih-alih mengumpulkan beberapa target dan menjalankanmycommand
hanya sekali.Namun, GNU
find
tidak mendukung misalnyakarena GNU
find
hanya mendukung kombinasi literal{} +
alih-alih lebih umum{} additional parameters +
. Perhatikan bahwa tidak mungkin ada apa pun antara kawat gigi dan+
karakter. Jika Anda mencoba ini, Anda akan mendapatkan kesalahan yang sama:Solusinya adalah menggunakan sintaks
{} additional parameters \;
yang berfungsi tetapi akan menjalankan perintah sekali untuk setiap target yang ditemukan. Jika Anda membutuhkan lebih banyak kinerja dengan GNUfind
Anda harus menulis skrip wrapper yang dapat menambahkan parameter tambahan ke argumen yang diberikan. Sesuatu sepertiharus cukup baik. Atau, jika Anda tidak ingin membuat file sementara, Anda dapat menggunakan satu-baris untuk mengubah urutan parameter seperti ini:
yang akan dieksekusi
mycommand {list of ttf files} extra arguments
. Perhatikan bahwa Anda mungkin perlu menggandakan karakter khusus untuk bash setelah-c
bendera.sumber
find
, tetapi perilaku yang benar yang ditentukan oleh POSIX .find
Anda mungkin memiliki GNUcp
. Dalam hal ini Anda bisafind ... -exec cp --target-directory ~/.fonts {} +
menyimpan{}
di akhir string eksekusi.find . -type f -perm 0777 -exec chmod 644 {}\;
mendapat kesalahan
find: missing argument to ``-exec'
.Menambahkan ruang di antara
{}
dan\
memperbaikinya:find . -type f -perm 0777 -print -exec chmod 644 {} \;
sumber
find
perintah di pertanyaan yang dihadapi.+
bentuk-exec
opsi untukfind
. Jawaban ini memperbaiki masalah yang tidak dimiliki pengguna yang mengajukan pertanyaan.Saya mengalami sakit kepala dengan sintaks exec di masa lalu. hampir setiap hari saya lebih suka sintaks bash yang lebih bagus:
Ini memiliki beberapa keterbatasan ketika Anda ingin memperlakukan file sebagai grup, karena masing-masing dievaluasi secara seri, tetapi Anda dapat menyalurkan output di tempat lain dengan baik
sumber
find … -exec … \;
, jadi tidak ada alasan untuk menggunakan ini bahkan jika Anda tahu bahwa nama file Anda jinak.exec
adalah terlalu banyak sakit kepala selama 5 menit yang ingin saya habiskan untuk ini. Nama file saya jinak dan ini menyelesaikan masalah saya :)