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.
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