GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Gruppen mit Awk oder Grep erfassen?

Ich möchte jedes gefundene Muster durchlaufen und Zugriff auf die verschiedenen Erfassungsgruppen innerhalb der Schleife haben, möglicherweise mit grep oder awk (Ich möchte wenn möglich bei ihnen bleiben, um zu vermeiden, dass ich ein drittes lerne, aber wenn es wirklich nötig ist, lerne ich ein anderes!)

Macht so etwas wie:

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

vorhanden?

Beispieltext:

blah12687hello=123
nothingthatmatches
blah3211hello=123456
blah15butnottheotherpattern

Mit der zuvor erwähnten Schleife sollte es Folgendes ausgeben:

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

Akzeptierte Antwort:

Die bash Shell selbst bietet eine Möglichkeit, die erfassten Gruppen nach Bedarf mit regulären Ausdrücken zu verarbeiten.

Der =~ Operator innerhalb eines Testausdrucks in doppelten Klammern, [[ mit der Übereinstimmungszeichenfolge auf der linken Seite des Operators und dem regulären Ausdruck als rechtem Operand.

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

Wenn der Ausdruck mit der Zeichenfolge übereinstimmt, wird der übereinstimmende Teil der Zeichenfolge in BASH_REMATCH gespeichert Array, über das geloopt werden kann, um auf die einzelnen erfassten Gruppen zuzugreifen. Der Exit-Status ist wenn der reguläre Ausdruck übereinstimmt, 1 wenn nicht, und 2 wenn der Ausdruck ungültig ist.

Angenommen, Sie haben die Eingabezeilen in einem Array gespeichert und die Wörter blah und hello sind feste Muster

#!/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

Wie Sie im obigen Code sehen können, können wir den BASH_REMATCH durchlaufen, sobald wir den Regex als wahr abgeglichen haben -Array, um jede der erfassten Gruppen zu drucken. Die Gesamtausgabe des Skripts würde in etwa so aussehen

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.

Wie Sie den BASH_REMATCH[0] sehen können enthält immer den Teil des Strings, der von der Regex erfolgreich gefunden wurde, und die einzelnen erfassten Gruppen sind über den Index 1 erreichbar weiter. Sie können benutzerdefinierte Logik schreiben, um jede der erfassten Gruppen zu verarbeiten, was Sie ursprünglich beabsichtigt hatten.

Verwandte:Welches ist das portabelste von sed, awk, perl und sh?

Wenn Sie daran interessiert sind, eine Dateieingabe zu lesen, verwenden Sie einfach ein while Schleife mit Eingabeumleitung auf die zu verarbeitende Datei

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. Gemeinsame Nutzung zusätzlicher Gruppen mit Podman-Containern

  2. Grep mit logischen Operatoren?

  3. Linux-Benutzergruppen verwalten

  4. Verwalten Sie Sicherheitsgruppen und -regeln

  5. grep:Gruppenerfassung

Ändern Sie Gruppen in Linux mit dem Befehl groupmod

Löschen Sie Gruppen in Linux mit dem Befehl groupdel

Erstellen Sie neue Gruppen in Linux mit dem Groupadd-Befehl

Gruppenverwaltungsbefehle in Linux

Grep-Befehl in Linux (mit Beispielen)

10 praktische Beispiele für Regex mit grep