Verwenden Sie den Befehl sed, um eine Bedingung anzuwenden und zu überprüfen, ob ein Muster übereinstimmt

8

Ich suche nach der Zeichenfolge ::=BEGINund möchte eine Bedingung anwenden, um zu überprüfen, ob das Wort gefunden wurde.

Was ich damit meine, ist etwas in dieser Richtung:

if (sed command does find a match for "::=BEGIN")
then i=1 
else i=0

Außerdem möchte ich, dass 1 (für yes found) und 0 (not found) in die Variable "i" eingefügt werden.

Bitte hilf mir. Erklären Sie auch die Lösung! Vielen Dank!

SamFlynn
quelle
grep '::= BEGIN' filename &> /dev/nullund dann überprüfen $?.
Nykakin
2
@ Nykakin grep hat -q Option, die den gleichen Job macht wie&> /dev/null
Sergiy Kolodyazhnyy
Ich habe eine sedVersion für Sie =)
AB

Antworten:

6

grep macht diesen Job gut genug.

$ echo "::=BEGIN" > testfile1.txt

$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND"
FOUND

$ grep "::=BEGIN" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
FOUND

$ grep "whever" -q testfile1.txt && echo "FOUND" || echo "NOTFOUND"
NOTFOUND

Der Code führt einfach eine stille Suche innerhalb der Subshell durch. &&Der logische UND-Operand prüft, ob der erste Befehl erfolgreich war. Wenn dies der Fall ist, wird er ausgeführt echo "FOUND". ||prüft, ob dieses Echo ausgeführt wurde, dh ob wir etwas gefunden haben. Das zweite Echo wird nur ausgeführt, wenn der erste Befehl fehlgeschlagen ist.

Hier ist eine awkVersion:

$ awk '{i="NOTFOUND";if($0~/::=BEGIN/) i="FOUNDIT";exit } END { print i}' testfile1.txt
FOUNDIT

$ awk '{i="NOTFOUND";if($0~/whatevs/) i="FOUNDIT";exit } END { print i}' testfile1.txt
NOTFOUND

Grundidee ist hier einstellen izu NOTFOUND, und wenn wir den String finden - ändern es FOUNDIT. Am Ende, nachdem der erste Satz der Verarbeitungsdatei fertig ist, werden wir drucken iund erfahren, ob wir etwas gefunden haben oder nicht.

Bearbeiten: In dem Kommentar haben Sie erwähnt, dass Sie das Ergebnis in eine Variable einfügen möchten. Shell stellt bereits eine Variable bereit, die den Exit-Status des vorherigen Befehls meldet $0. Exit Status 0 bedeutet Erfolg, alles andere - scheitern. Zum Beispiel,

$ grep "::=BEGIN" -q testfile1.txt  
$ echo $?
0

Wenn Sie den Exit-Status in einer Variablen verwenden möchten, können Sie dies folgendermaßen tun : MYVAR=$(echo $?). Erinnerst du dich, $? Exit-Status des vorherigen Befehls melden. Sie müssen dies also direkt nach dem Befehl grep verwenden.

Wenn Sie weiterhin meine früheren Einzeiler awk und grep verwenden möchten, können Sie denselben Trick verwenden MYVAR=$()und den gewünschten Befehl zwischen die geschweiften Klammern setzen. Die Ausgabe wird der Variablen zugewiesen MYVAR.

Sergiy Kolodyazhnyy
quelle
Der Benutzer, der die Antwort abgelehnt hat, hinterlässt bitte einen Kommentar, in dem erklärt wird, warum Sie die Antwort abgelehnt haben
Sergiy Kolodyazhnyy
Ich weiß nichts über die Ablehnung (ich habe nicht die Wiederholungspunkte, um etwas zu tun). Mir fehlen viele Kenntnisse in GREP und SED (was zu diesem Zeitpunkt mein Hauptaugenmerk ist). Irgendeine Idee zu guten Ressourcen, von denen aus ich SED machen kann? Bereits bei Google nachgeschlagen, erklären die meisten Websites nicht richtig, sie verwenden hier nur Schrägstriche und ihre und Sachen werden ersetzt und ausgetauscht bla bla bla.
SamFlynn
@ user2446359 ja, das ist sed'sSyntax, die manchmal zu einem riesigen Durcheinander werden kann. Außerdem ist es ein Werkzeug zum Bearbeiten von Sachen, nicht zum Suchen. grepist das richtige Werkzeug dafür. In Ihrer ursprünglichen Frage haben Sie nicht erwähnt, dass Sie das Ergebnis in eine Variable einfügen. Bitte fügen Sie das hinzu. Ich werde meine Antwort in einer Sekunde bearbeiten, um diese Anforderung zu erfüllen
Sergiy Kolodyazhnyy
@ user2446359 Bearbeitung ist abgeschlossen, bitte sehen Sie es
Sergiy Kolodyazhnyy
Vielen Dank Serg! Meinen Tag gerettet. Ich werde das Echo $ verwenden? und speichern Sie es in einer Variablen.
SamFlynn
6

Mit einer GNU sed (wie standardmäßig auf jedem Ubuntu-System installiert) :

{ sed -n '/::=BEGIN/Q 1'; i=$?; } <infile

Einige Fakten zu dieser Antwort:

  1. sed Quits Eingabe, sobald die allererste Übereinstimmung irgendwo in der Datei gefunden wird - was bedeutet, dass keine Zeit mehr damit verschwendet wird, die Datei weiterzulesen.

  2. sed Gibt in seinem Exit-Code den numerischen Wert 0 oder 1 zurück, je nachdem, ob der adressierte reguläre Ausdruck nicht gefunden werden konnte / konnte.

  3. $iwird sedbeim Verlassen auf 's return gesetzt.

  4. Die {Gruppierung ; }wird verwendet, um mögliche Umleitungsfehler zuverlässig zu behandeln. Sie $iwird nicht festgelegt, wenn die Shell die Datei überhaupt nicht öffnen kann, um Fehlalarme zu vermeiden.

Dies sollte jedoch wahrscheinlich nicht vorgezogen grep -qwerden, da dies im Grunde auch alle oben genannten Aufgaben ausführen kann (wenn umgekehrt) , POSIXly und normalerweise schneller.

Die bereits gegebene grep -qAntwort ist sehr gut, aber etwas kürzer:

grep -q pattern ./infile; i=$((!$?))
mikeserv
quelle
4

Sie können dies verwenden:

#!/bin/bash
while IFS= read -r line; do
    case "$line" in *::=BEGIN*) i=1 && break;;         
                               *) i=0
    esac
done <file.txt

Dadurch wird die Datei file.txtzeilenweise durchsucht. Wenn eine Übereinstimmung ::=BEGINgefunden wird, wird die Variable festgelegt i=1und beendet. Wird keine Übereinstimmung gefunden, wird die Variable auf gesetzt i=0.

heemayl
quelle
3

Meine sedVersion

sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'

in einer Variablen speichern i:

i=$(sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}')

Beispiel:

$ echo "::=BEGIN" > foo
$ echo "::=BEGIN" >> foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}' 
1
$ echo "::=NOT_BEGIN" > foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}'
0
$ echo "::=BEGIN" >> foo
$ sed ':a;N;$!ba;s/\n/ /g' foo | sed '{/::=BEGIN/{s/.*/1/; b next}; s/.*/0/; :next}' 
1

Erläuterung:

  • Wenn ::=BEGINgefunden, drucken Sie a 1und springen Sie zunext
  • Wenn ::=BEGINnicht gefunden, drucken Sie0
AB
quelle
2
Gute Arbeit, Kumpel ! Ich mag es
Sergiy Kolodyazhnyy
@terdon korrigiert
AB
2

sed(Stream EDitor ) ist nicht das richtige Werkzeug für diese Art von Dingen: Sie können einfach eine bash ifAnweisung verwenden, um Ihre Eingabe mit einem regulären Ausdruck abzugleichen:

#!/bin/bash

#...
input="$(< inputfile)"
[[ "$input" =~ ::=BEGIN ]] && i=1 || i=0
#...
  • input="$(< inputfile)": weist inputfileder Variablen den Inhalt von zu$input
  • [[ "$input" =~ ::=BEGIN ]] && i=1 || i=0: vergleicht den regulären Ausdruck ::=BEGINmit dem Inhalt der Variablen $input; wenn es ein Spiel ist es ordnet 1an $i, andernfalls ordnet sie 0zu$i
kos
quelle
Siehe die Kommentare unter meiner Antwort
Sergiy Kolodyazhnyy