GNU/Linux >> Belajar Linux >  >> Ubuntu

Bagaimana Seseorang Dapat Menggabungkan Serangkaian Pernyataan Grep yang Disambungkan Menjadi Satu Pernyataan Grep?

Saya ingin tahu apakah ada cara untuk menggabungkan serangkaian pernyataan grep di mana efeknya adalah "dan" ekspresi daripada "atau" ekspresi yang cocok.

Demo di bawah ini:

./script  
     From one grep statement, I want output like this
a b c

     not like this
a
c
a b
a b c
a b c d

Mendengar adalah melihat script.

 #!/bin/bash
 string="a
 b
 c
 d
 a b
 a b c
 a b c d"

 echo -e "\t From one grep statement I want output like this"
 echo "$string" |
 grep a |grep c |grep -v d #Correct output but pipes three grep statements

 echo -e "\n\tNot like this"
 echo "$string" |
 grep -e'a' -e'c' -e-v'd' #One grep statement but matching expressions are "or" versus "and"

Jawaban yang Diterima:

Anda tidak dapat mengubah filter grep a | grep c | grep -v d ke satu grep . sederhana . Hanya ada cara yang rumit dan tidak efektif. Hasilnya memiliki kinerja yang lambat dan makna ekspresinya kabur.

Kombinasi perintah tunggal dari tiga grep

Jika Anda hanya ingin menjalankan satu perintah, Anda dapat menggunakan awk yang bekerja dengan ekspresi reguler juga dan dapat menggabungkannya dengan operator logika. Ini setara dengan filter Anda:

awk '/a/ && /c/ && $0 !~ /d/'

Saya pikir dalam banyak kasus tidak ada alasan untuk menyederhanakan pipa menjadi satu perintah kecuali ketika kombinasi menghasilkan ekspresi grep yang sangat sederhana yang bisa lebih cepat (lihat hasil di bawah).

Sistem mirip Unix dirancang untuk menggunakan pipa dan menghubungkan berbagai utilitas bersama-sama. Meskipun komunikasi pipa bukanlah yang paling efektif tetapi dalam banyak kasus itu sudah cukup. Karena saat ini sebagian besar komputer baru memiliki banyak inti CPU, Anda dapat "secara alami" memanfaatkan paralelisasi CPU hanya dengan menggunakan pipa!

Filter asli Anda bekerja dengan sangat baik dan menurut saya dalam banyak kasus awk solusi akan menjadi sedikit lebih lambat bahkan pada satu inti.

Perbandingan kinerja

Dengan menggunakan program sederhana, saya telah membuat file pengujian acak dengan 200 000 000 baris, masing-masing dengan 4 karakter sebagai kombinasi acak dari karakter a , b , c dan d . File memiliki 1 GB. Selama pengujian, itu benar-benar dimuat dalam cache sehingga tidak ada operasi disk yang memengaruhi pengukuran kinerja. Pengujian dijalankan pada Intel dual core.

Satu grep

$ time ( grep -E '^[^d]*a[^d]*c[^d]*$|^[^d]*c[^d]*a[^d]*$' testfile >/dev/null )
real    3m2.752s
user    3m2.411s
sys 0m0.252s

Satu awk

$ time ( awk '/a/ && /c/ && $0 !~ /d/' testfile >/dev/null )
real    0m54.088s
user    0m53.755s
sys 0m0.304s

Tiga grep asli disalurkan

$ time ( grep a testfile | grep c | grep -v d >/dev/null )
real    0m28.794s
user    0m52.715s
sys 0m1.072s

Hibrida – gabungan grep positif, pipa negatif

$ time ( grep -E 'a.*c|c.*a' testfile | grep -v d >/dev/null )
real    0m15.838s
user    0m24.998s
sys 0m0.676s

Di sini Anda melihat bahwa grep single tunggal sangat lambat karena ekspresi yang kompleks. Pipa asli tiga grep cukup cepat karena paralelisasi yang baik. Tanpa paralelisasi – pada satu inti – pipa asli berjalan sedikit lebih cepat dari awk yang sebagai satu proses tidak diparalelkan. Awk dan grep mungkin menggunakan kode ekspresi reguler yang sama dan logika dari dua solusi serupa.

Terkait:Berapa tahun 11,10 didukung?

Pemenang yang jelas adalah hybring yang menggabungkan dua grep positif dan meninggalkan grep negatif di dalam pipa. Tampaknya ekspresi reguler dengan | tidak memiliki penalti kinerja.


Ubuntu
  1. Bagaimana saya bisa mencari pola multiline dalam sebuah file?

  2. Bagaimana saya bisa menggunakan grep untuk hanya menampilkan nama file di Linux?

  3. Bagaimana cara gzip banyak file menjadi satu file gz?

  1. Bagaimana Cara Memindahkan Satu Direktori ke Bawah?

  2. Bagaimana Cara Masuk Ke Wadah Lxc?

  3. Bagaimana cara menggabungkan dua perpustakaan statis menjadi satu?

  1. Bagaimana saya bisa mengecualikan direktori dari grep -R?

  2. Bagaimana cara menggabungkan beberapa baris keluaran menjadi satu baris?

  3. Gabungkan beberapa perintah unix menjadi satu output