Saya sedang mencari cara untuk mencari file di mana ada dua contoh kata dalam file yang sama. Saya telah menggunakan yang berikut untuk melakukan pencarian saya hingga saat ini:
find . -exec grep -l "FIND ME" {} \;
Masalah yang saya temui adalah bahwa jika tidak ada satu ruang yang tepat antara "TEMUKAN" dan "AKU", hasil pencarian tidak menghasilkan file. Bagaimana cara saya mengadaptasi string pencarian sebelumnya di mana kedua kata "TEMUKAN" dan "AKU ada dalam file yang bertentangan dengan" TEMUKAN AKU "?
Saya menggunakan AIX.
grep -E
/egrep
yang menggambarkan semua pola yang Anda minati (dan menggunakan+
alih-alih;
jika+
Jawaban:
Dengan alat GNU:
Anda dapat melakukannya secara standar:
Tapi itu akan menjalankan dua greps per file. Untuk menghindari menjalankan yang banyak
grep
dan masih dapat dibawa-bawa sementara masih memungkinkan karakter apa pun dalam nama file, Anda dapat melakukan:Gagasannya adalah untuk mengubah output
find
menjadi format yang cocok untuk xargs (yang mengharapkan blank (SPC / TAB / NL, dan blank lainnya dari lokal Anda dengan beberapa implementasixargs
) daftar kata-kata yang terpisah di mana single, double quotes dan backslash dapat melarikan diri kosong dan satu sama lain).Secara umum Anda tidak dapat memposting proses keluaran
find -print
, karena memisahkan nama file dengan karakter baris baru dan tidak lepas dari karakter baris baru yang ditemukan dalam nama file. Sebagai contoh jika kita melihat:Kami tidak punya cara untuk mengetahui apakah itu satu file yang dipanggil
b
dalam direktori yang disebuta<NL>.
atau apakah itu dua filea
danb
.Dengan menggunakan
.//.
, karena//
tidak dapat muncul sebaliknya di jalur file sebagai keluaran olehfind
(karena tidak ada yang namanya direktori dengan nama kosong dan/
tidak diizinkan dalam nama file), kita tahu bahwa jika kita melihat baris yang berisi//
, maka itu baris pertama dari nama file baru. Jadi kita bisa menggunakanawk
perintah itu untuk menghindari semua karakter baris baru tetapi yang mendahului baris-baris itu.Jika kita mengambil contoh di atas,
find
akan menampilkan dalam kasus pertama (satu file):Awk yang lolos ke:
Sehingga
xargs
melihatnya sebagai satu argumen. Dan dalam kasus kedua (dua file):Yang
awk
akan pergi apa adanya, jadixargs
melihat dua argumen.sumber
find ... -print0
dangrep --null
sebagai gantinya?grep --null
(alias -Z) digunakan pada yang pertama tetapi merupakan ekstensi GNU.-print0
(ekstensi GNU lain) tidak akan membantu di sini..//.
artinya, dan bertanya-tanya bagaimana saya bisa memodifikasi itu untuk menerima argumen dari baris perintah, katakan$1
?-print0
denganfind
dan-0
denganxargs
?find -print0
jawaban saya di mana pun.Jika file-file tersebut dalam satu direktori dan nama mereka tidak mengandung spasi, tab, baris baru,
*
,?
atau[
karakter dan tidak mulai dengan-
atau.
, ini akan mendapatkan daftar file yang berisi ME, kemudian mempersempit yang turun ke orang-orang yang juga mengandung FIND.sumber
grep -l CategoryLinearAxis `grep -l labelJsFunction *`
sambil mencari file yang memiliki kedua atribut di dalamnya. Sungguh cara yang sempurna untuk melakukannya. +1Dengan
awk
Anda juga bisa menjalankan:Menggunakan
cx
dancy
menghitung untuk pencocokan garisFIND
dan masing-masingME
. DiEND
blok, jika kedua penghitung> 0, itu mencetakFILENAME
.Ini akan lebih cepat / lebih efisien dengan
gnu awk
:sumber
Atau gunakan
egrep -e
ataugrep -E
suka ini:find . -type f -exec egrep -le '(ME.*FIND|FIND.*ME)' {} \;
atau
find . -type f -exec grep -lE '(ME.*FIND|FIND.*ME)' {} +
Make
+
make find (jika didukung) menambahkan beberapa nama file (path) sebagai argumen pada perintah yang sedang-exec
diedit. Ini menyimpan proses dan jauh lebih cepat daripada\;
yang memanggil perintah satu kali untuk setiap file yang ditemukan.-type f
hanya cocok dengan file, untuk menghindari grepping pada direktori.'(ME.*FIND|FIND.*ME)'
adalah ekspresi reguler yang cocok dengan setiap baris yang mengandung "ME" diikuti oleh "FIND" atau "FIND" diikuti oleh "ME". (Kutipan tunggal untuk mencegah shell menafsirkan karakter khusus).Tambahkan a
-i
kegrep
perintah untuk membuatnya case-sensitive.Untuk hanya mencocokkan garis di mana "TEMUKAN" muncul sebelum "AKU", gunakan
'FIND.*ME'
.Untuk membutuhkan spasi (1 atau lebih, tetapi tidak ada yang lain) antara kata-kata:
'FIND +ME'
Untuk mengizinkan spasi (0 atau lebih, tetapi tidak ada yang lain) di antara kata-kata:
'FIND *ME'
Kombinasi ini tidak ada habisnya dengan ekspresi reguler, dan asalkan Anda tertarik untuk mencocokkan hanya berdasarkan baris-per-waktu, egrep sangat kuat.
sumber
find
dalam pertanyaan.Melihat jawaban yang diterima, tampaknya lebih kompleks daripada yang seharusnya. Versi GNU
find
dangrep
danxargs
mendukung string yang diakhiri NULL. Sesederhana:Anda dapat memodifikasi
find
perintah Anda untuk memfilter ke file yang Anda inginkan, dan itu berfungsi dengan nama file yang mengandung karakter apa pun; tanpa menambahkan kompleksitassed
parsing. Jika Anda ingin memproses file lebih lanjut, tambahkan yang lain--null
ke yang terakhirgrep
Dan, sebagai fungsi:
Jelas, gunakan jawaban yang diterima jika Anda tidak menjalankan versi GNU dari alat-alat ini.
sumber
--null
,--print0
,-0
Semua ekstensi GNU. Meskipun beberapa dari mereka ditemukan dalam implementasi lain saat ini, mereka masih tidak portabel dan tidak dalam standar POSIX atau Unix.