Saya mencari file berdasarkan ekspresi reguler, dan kemudian saya mencoba mencari file tersebut untuk konten. Jadi, misalnya, saya punya sesuatu seperti
#Find all C++ files that match a certain pattern and then search them
find . -name "*.cpp" | grep "<name regex>" | xargs grep "<content regex>"
Masalah yang saya hadapi adalah bahwa beberapa jalur memiliki ruang di dalamnya, yang membingungkan xargs
. Saya tahu bahwa jika saya hanya menggunakan find
, saya bisa menggunakan -print0
argumen (bersama dengan -0
argumen pada xargs
) untuk menjaga xargs dari memperlakukan ruang sebagai pembatas. Apakah ada yang serupa grep
?
Atau apakah saya mendekati masalah ini dengan cara yang salah sepenuhnya? Naif, find
untuk grep
untuk xargs grep
masuk akal bagi saya, tapi aku terbuka untuk pendekatan lain yang menghasilkan hasil yang sama.
xargs
menggunakan-i
parameter, alacat sample.txt | grep "pat t ern" | xargs -i grep "{}"
- kurung kurawal memberi tahu di mana posisi argumen. Manual mengatakan kepada saya bahwa-i
sudah usang dalam mendukung-I
jadi mungkin perlu melihat itu juga.Jawaban:
Gunakan sesuatu seperti ini mungkin (jika gnu grep).
bung
Juga lihat opsi untuk pembatas nol.
sumber
grep -r include='*.cpp'
ini adalah shell glob - dan begitu juga fitur-aligned w /find . -name '*.cpp' -exec grep -e 'content_pattern' -- {} \;
not w /find . -name '*.cpp' | grep 'name_pattern' | xargs grep 'content_pattern'
Jika Anda harus melompati banyak rintangan, maka efisiensi xargs akan hilang. Ini adalah satu pekerjaan kasar:
Setiap kali saya mengalami masalah dengan spasi dalam nama file, jawabannya adalah tanda kutip ganda pada variabel.
sumber
Gunakan
find
untuk melakukan semua penyaringan nama file. Daripadamelakukan
Jika Anda ingin melakukan sesuatu yang sedikit lebih rumit, sukai
Anda dapat melakukan
Perhatikan bahwa ini harus bekerja bahkan untuk file dengan baris baru di namanya.
Dan, jika Anda membutuhkan kekuatan ekspresi reguler penuh, Anda dapat menggunakan
-regex
.sumber
Ini harus bekerja bahkan tanpa alat GNU:
The
perl
panggilan menggantikan jeda baris dengan karakter null, yang akan memungkinkanxargs -0
untuk menafsirkan input pada basis per-line daripada basis per-spasi.Dengan menggunakan GNU, Anda dapat menghapus
perl
panggilan dan mengubahnyaxargs -0 …
kexargs -d "\n" …
Tidak punya
perl
atau GNU? Cobaawk '{printf "%s%c", $0, 0}'
saja.sumber
xargs -d "\n"
. Itu kejadian yang sangat tidak biasa, tetapi jika Anda tidak memiliki kendali atas data dan khawatir itu menjadi risiko keamanan, berhati-hatilah dengan ekspektasi keluaran.