Unterscheidet grep eine Variable und den $ regex?

Sep 26 2020

Ich möchte nach einer Variablen testsuchen , die die Zeichenfolge enthält , aber ich möchte auch sicherstellen, dass sie nur testdann gefunden wird, wenn dies das einzige Wort in einer Zeile ist.

Also habe ich das versucht:

string=test
echo "test" | grep "$string$"

Ich würde gerne wissen, ob ich grepweiß, dass der erste Teil $string(in grep " $ string $") nach dem String sucht test, während der letzte Teil $(in grep "$ string $ " nach dem String fragt test, aber nichts soll nach testin der Leitung. Ist die grepLage zu unterscheiden , $stringals eine Variable und nur $als regex für Ende der Leitung, oder muß ich eine bestimmte Art und Weise verwenden , um sie auseinander zu unterscheiden?

Antworten

15 Quasímodo Sep 26 2020 at 21:20

Grep weiß nichts, was es nicht sieht. Wenn grep sieht $string$, wird versucht, eine Übereinstimmung zu finden $string{end-of-line}. Was passiert ist, dass die Shell die Variable erweitert, $stringbevor sie grepstartet, so dass sie als Regex grepempfängt test$.

Aber $string$warum wird angesichts des Wortes das Letzte $nicht erweitert, solange es $stringist? Weil $ist kein gültiger Variablenname. Dies ist in der POSIX-Spezifikation sehr deutlich :

Wenn der Parameter nicht in geschweiften Klammern steht und ein Name ist, verwendet die Erweiterung den längsten gültigen Namen (siehe XBD-Name ), unabhängig davon, ob die durch diesen Namen dargestellte Variable vorhanden ist oder nicht.

Und XBD Name Staaten

In der Shell-Befehlssprache ein Wort, das ausschließlich aus Unterstrichen, Ziffern und Alphabeten aus dem tragbaren Zeichensatz besteht. Das erste Zeichen eines Namens ist keine Ziffer.

Und es gibt auch spezielle Parameter , wie zum Beispiel $$, $@, $#, etc ..

Wenn Sie sich nicht an all dies erinnern möchten, folgen Sie einfach den Ratschlägen von Gordon Davisson und entkommen Sie allen $, die keine Variable einführen sollten, um sicherzustellen, dass sie erhalten bleibt.

$ echo "$string$" test$
$ echo "$string\$" test$
$ echo "\$string\$" $string$

Denken Sie auch daran, dass Variablen in doppelten Anführungszeichen, jedoch nicht in einfachen Anführungszeichen erweitert werden.

$ echo 'test' | grep '$string$'   # No match, $string is not expanded $ echo 'test' | grep "$string$"   # Match, $string is expanded
test

Ich möchte nach einer Variablen testsuchen , die die Zeichenfolge enthält , aber ich möchte auch sicherstellen, dass sie nur testdann gefunden wird, wenn dies das einzige Wort in einer Zeile ist.

Dazu benötigen Sie entweder den regulären Ausdruck ^test$(um die Zeichenfolge sowohl am Anfang als auch am Ende der Zeile zu verankern) oder das -xFlag vongrep . Ihr ursprünglicher Versuch würde übereinstimmen, Atestda der reguläre Ausdruck test$nicht am Zeilenanfang verankert ist.

$ echo Atest | grep "$string$"
Atest
$ echo Atest | grep -x "$string"
$ echo Atest | grep "^$string$"