Apa perbedaan antara `grep`,` egrep`, dan `fgrep`?

273

Bisa ada yang bilang saya perbedaan teknis antara grep, egrep, dan fgrepdan memberikan contoh yang cocok?

Kapan saya perlu menggunakan greplebih egrepdan sebaliknya?

mr_eclair
sumber
7
superuser memiliki ilustrasi hebat tentang perbedaan antara grep, egrep, fgrep dan pgrep: superuser.com/questions/508881/…
Eric Leschinski

Jawaban:

292
  • egrep adalah 100% setara dengan grep -E
  • fgrep adalah 100% setara dengan grep -F

Secara historis switch ini disediakan dalam biner yang terpisah. Pada beberapa sistem Unix yang benar-benar tua Anda akan menemukan bahwa Anda perlu memanggil binari yang terpisah, tetapi pada semua sistem modern sakelar lebih disukai. Halaman manual untuk grep memiliki perincian tentang ini.

Adapun apa yang mereka lakukan, -Eberalih grep ke mode khusus sehingga ekspresi dievaluasi sebagai ERE (Extended Regular Expression) yang bertentangan dengan pencocokan pola normal. Detail sintaksis ini ada di halaman manual.

-E, --extended-regexp
Menafsirkan POLA sebagai ekspresi reguler yang diperluas

The -Fberalih beralih grep menjadi modus yang berbeda di mana ia menerima pola untuk mencocokkan, tapi kemudian membagi pola yang menjadi satu string pencarian per baris dan melakukan pencarian OR pada salah satu string tanpa melakukan pencocokan pola khusus.

-F, --fixed-strings
Menafsirkan POLA sebagai daftar string tetap, dipisahkan oleh baris baru, yang mana saja yang harus dicocokkan.

Berikut ini beberapa contoh skenario:

  • Anda memiliki file dengan daftar katakanlah nama pengguna Unix dalam teks biasa. Anda ingin mencari file grup di mesin Anda untuk melihat apakah ada di antara sepuluh pengguna yang terdaftar di grup khusus:

    grep -F -f user_list.txt /etc/group
    

    Alasan -Fsaklar membantu di sini adalah bahwa nama pengguna dalam file pola Anda ditafsirkan sebagai string teks biasa. Dots misalnya akan diartikan sebagai dots daripada wild-card.

  • Anda ingin mencari menggunakan ekspresi mewah. Misalnya tanda kurung ()dapat digunakan untuk menunjukkan grup yang |digunakan sebagai operator OR. Anda dapat menjalankan pencarian ini menggunakan -E:

    grep -E '^no(fork|group)' /etc/group
    

    ... untuk mengembalikan garis yang dimulai dengan "nofork" atau "nogroup". Tanpa -Esaklar Anda harus melarikan diri dari karakter khusus yang terlibat karena dengan pencocokan pola normal mereka hanya akan mencari pola yang tepat;

    grep '^no\(fork\|group\)' /etc/group
    
Caleb
sumber
17
Beberapa sistem tidak memiliki egrepatau fgrep; -Edan -Fstandar. Sebenarnya ada ketidakcocokan kecil di egrep: itu memperlakukan {sedikit berbeda.
Gilles
4
fgrepmenggunakan backend Aho-Corasick, sementara grepmenggunakan versi modifikasi dari Commentz-Walter. Ini berarti grepmemiliki kompleksitas kasus terburuk O (mn) dan fgrepO terburuk (m + n).
Slater Victoroff
2
Gilles "au contraire mon capitan", beberapa sistem (mungkin lebih tua) mungkin tidak memiliki opsi -F untuk grep standar tetapi memiliki fgrep, beberapa orang mengeluh tentang hal itu pada utas asli yang saya temukan tentang penggunaan grep untuk karakter khusus
PENULIS
Saya baru-baru ini terjadi pada sistem Android di mana egrepdan grep -Editangani oleh berbagai executable, BusyBox dan BSD grep. Kedua varian memiliki perbedaan perilaku untuk konstruksi regex non-Posix, seperti \s. Ini menyebabkan banyak kebingungan ...
Lii
33

Dari man grep:

 egrep sama dengan grep -E.
 fgrep sama dengan grep -F. Doa langsung sebagai egrep atau  
  fgrep sudah usang, tetapi disediakan untuk memungkinkan aplikasi historis
  yang bergantung pada mereka untuk menjalankan tidak dimodifikasi.

Anda menggunakan fgrepatau grep -Fjika Anda tidak ingin grepped string ditafsirkan sebagai suatu pola.

Anda menggunakan egrepatau grep -Ejika Anda perlu menggunakan regexp tambahan.

rozcietrzewiacz
sumber
13

egrepdan fgreppada dasarnya setara dengan grep -Edan grep -F(masing-masing):

   -E, --extended-regexp
          Interpret PATTERN as an extended regular  expression  (ERE,  see
          below).  (-E is specified by POSIX.)

   -F, --fixed-strings
          Interpret  PATTERN  as  a  list  of  fixed strings, separated by
          newlines, any of which is to be matched.  (-F  is  specified  by
          POSIX.)

Pesan kesalahan mungkin berbeda.

Stéphane Gimenez
sumber
2
ok, tapi apa itu ekspresi reguler yang diperluas? Itu tidak benar-benar menjelaskan di bawah ini. Beberapa contoh akan menyenangkan ...
isomorphismes
@isomorphismes: Tautan wikibooks ini menjelaskannya dengan baik ...
zb226
8

Dari "man grep":

tiga varian program egrep, fgrep dan rgrep tersedia. egrep sama dengan grep -E. fgrep sama dengan grep -F. rgrep sama dengan grep -r. Doa langsung baik sebagai egrep atau fgrep sudah usang, tetapi disediakan untuk memungkinkan aplikasi historis yang bergantung pada mereka untuk berjalan tanpa dimodifikasi.

Rufo El Magufo
sumber
2
Pertanyaannya menanyakan contoh yang cocok.
isomorfisma
3

Jika Anda mencari string kata demi kata, dan ingin memastikan bahwa string yang Anda sampaikan ditafsirkan secara kata demi kata (yaitu tanpa risiko yang mengatakan titik atau tanda tanya akan ditafsirkan sebagai sesuatu yang lain) gunakan fgrep atau egrep -F.

Adapun perbedaan antara egrep dan grep, saya pikir egrep adalah waktu yang paling Anda inginkan. Situs manual GNU mencantumkan perbedaan antara grep dan egrep yang tampaknya terletak pada sintaksis: beberapa hal memerlukan garis miring sedangkan yang lain tidak. Saya pikir egrep lebih "kompatibel" dengan perl regexps dan javascript regexps sehingga lebih mudah bagi saya untuk menggunakan egrep.

Btw. Saya benar-benar mendorong Anda untuk mencoba ACK - mendukung PREG, dan memiliki standar yang lebih berguna (yaitu mewarnai, melewatkan direktori yang mungkin bukan yang Anda inginkan seperti .svn, kemampuan untuk mengikuti symlink, dan sedikit lebih mudah untuk mengetik ack dari grep -E).

qbolec
sumber