GNU/Linux >> Belajar Linux >  >> Linux

Tangkap Grup Dengan Awk Atau Grep?

Saya ingin mengulang setiap pola yang ditemukan dan memiliki akses ke grup tangkapan yang berbeda di dalam loop, mungkin dengan grep atau awk (Saya ingin tetap bersama mereka jika memungkinkan untuk menghindari mempelajari yang ketiga, tetapi jika benar-benar perlu, saya akan mempelajari yang lain!)

Melakukan sesuatu seperti:

awk-or-grep -E '(blah(.*)hello=(.*))' sampletext | while read -r l; do 
    echo $0             #1st capture group
    echo $1             #2nd catpure group
    dosomethingwith $2  #3rd capture group
done

ada?

Contoh teks:

blah12687hello=123
nothingthatmatches
blah3211hello=123456
blah15butnottheotherpattern

Dengan loop yang disebutkan sebelumnya, seharusnya menampilkan:

blah12687hello=123
12687
<it should run the command dosomethingwith 123>
blah3211hello=123456
3211
<it should run the command dosomethingwith 123456>

Jawaban yang Diterima:

bash shell dengan sendirinya menyediakan cara untuk melakukan proses pencocokan ekspresi reguler kelompok yang ditangkap sesuai kebutuhan.

=~ operator dalam ekspresi pengujian tanda kurung ganda, [[ dengan string yang cocok di sisi kiri operator dan ekspresi reguler sebagai operan kanan.

if [[ "$str" =~ $re ]]; then

Jika ekspresi cocok dengan string, bagian string yang cocok disimpan di BASH_REMATCH array yang dapat dilingkarkan untuk mengakses grup yang diambil secara individual. Status keluarnya adalah jika regexp cocok, 1 jika tidak, dan 2 jika ekspresi tidak valid.

Sejauh menyangkut contoh Anda, dengan asumsi Anda memiliki baris input yang disimpan dalam array dan kata-kata blah dan hello adalah pola tetap

#!/usr/bin/env bash

exampleStr=('blah12687hello=123' 'nothingthatmatches' 'blah3211hello=123456' 'blah15butnottheotherpattern')

re='blah([[:digit:]]+)hello=([[:digit:]]+)'

for str in "${exampleStr[@]}"; do
    if [[ "$str" =~ $re ]]; then
       for group in "${BASH_REMATCH[@]}"; do
           printf "%s\n" "$group"
       done
    else
       printf "No match \n"
    fi
done

Seperti yang Anda lihat pada kode di atas, setelah kami mencocokkan regex dengan true, kami dapat mengulang BASH_REMATCH array untuk mencetak setiap grup yang diambil. Output skrip keseluruhan akan menjadi seperti

blah12687hello=123     # Value of BASH_REMATCH[0]
12687                  # Value of BASH_REMATCH[1]
123                    # Value of BASH_REMATCH[2]
Regex not matches.
blah3211hello=123456
3211
123456
Regex not matches.

Seperti yang Anda lihat BASH_REMATCH[0] selalu berisi bagian dari string yang berhasil dicocokkan oleh ekspresi reguler, dan grup yang diambil secara individual dapat diakses dari indeks 1 maju. Anda dapat menulis logika khusus untuk memproses setiap grup yang diambil yang merupakan tujuan awal Anda.

Terkait:Manakah yang paling portabel dari sed, awk, perl, dan sh?

Jika Anda tertarik untuk membaca input file, cukup gunakan while loop dengan input re-direction pada file yang akan diproses

while IFS= read -r line; do
    if [[ "$line" =~ $re ]]; then
       for group in "${BASH_REMATCH[@]}"; do
           printf "%s\n" "$group"
       done
    else
       printf "No match \n"
    fi
done < inputFile.txt

Linux
  1. Kelola grup pengguna Linux

  2. Kelola grup dan aturan keamanan

  3. grep:penangkapan grup

  1. Berbagi grup tambahan dengan wadah Podman

  2. Grep Dengan Operator Logika?

  3. Tangkap paket dengan tcpdump

  1. Perintah AWK di Linux dengan Contoh

  2. Menggunakan grep vs awk

  3. Cara grep keluaran ps dengan header