Warum muss mein Grep-Ausdruck $'string' verwenden, um Tabulatorzeichen abzugleichen?

Warum muss mein Grep-Ausdruck $'string' verwenden, um Tabulatorzeichen abzugleichen?

Wenn Sie diesen Code nehmen:

echo -e '\t\t\tString' | grep '^[\t]*String'

das Ergebnis ist leer, da es nicht übereinstimmt, dennoch dies:

echo -e '\t\t\tString' | grep $'^[\t]*String'

funktioniert. Ich schwöre, dass ich den Code der ersten Zeile hundertmal in meinen Skripten und im Terminal verwendet habe, ohne jemals das Zeichen „$“ auf diese Weise zu verwenden, und es schien immer zu funktionieren. Gab es kürzlich eine Änderung? Warum wird das Zeichen „$“ benötigt? Oder mache ich etwas falsch?

Antwort1

ANSI-C-Zitate

Laut Bash-Handbuch heißt dasANSI-C-ZitatIm Handbuch steht:

Wörter der Form$'Zeichenfolge'werden speziell behandelt. Das Wort wird zu einer Zeichenfolge erweitert, wobei durch Backslash maskierte Zeichen gemäß dem ANSI-C-Standard ersetzt werden.

In der Praxis bedeutet dies, dass '\t'nicht in ein Tabulatorzeichen erweitert wird, sondern $'\t'wird. Die Ausgabe sollte der Verwendung von entsprechen echo -e, kann aber überall dort verwendet werden, wo Sie eine Zeichenfolge verwenden würden, ohne dass dies erforderlich ist.Befehlsersetzung.

Dienstprogramme wie GNU sed führen ihre eigene Erweiterung von Escape-Zeichen durch, GNU grep jedoch nicht. Die Bash-Shell, nicht grep, erweitert Escape-Zeichen innerhalb von ANSI-C-Anführungszeichen. Ohne die ANSI-C-Anführungszeichen enthält der von Ihnen gepostete reguläre Ausdruck keine Tabulatorzeichen, die mit der Eingabe übereinstimmen.

Antwort2

Ihnen sollte klar sein, dass es nicht nur einen einzigen Typ regulärer Ausdrücke gibt. Es gibt mindestens basic regular expressionsoder BRE(manchmal nur RE), extended regular expressionsoder EREund perl compatible regular expressionsoder PCRE. Alle diese Sprachen verwenden leicht unterschiedliche Syntax. Aktuelle Versionen von GNU grepunterstützen alle drei und die BREsind Standard. Für EREmüssen Sie -Edie Option und für PCRE -Pdie Option verwenden. Ihr Beispiel funktioniert nur mit , -Pda der Backslash bei einfachem und erweitertem regulären Ausdruck seine Bedeutung verliert und [\t]entweder mit dem Backslash oder dem Zeichen t übereinstimmt. Sie haben dieses Muster wahrscheinlich in einer anderen Sprache verwendet, die standardmäßig unterstützt wird PCRE, was Sinn macht, da dies die leistungsstärkste Version ist. Oder vielleicht hatten Sie es alias grep='grep -P'irgendwo.

Antwort3

Die erste Zeile funktioniert, wenn Sie das weglassen ^. Vielleicht hat es funktioniert, aber nicht so, wie Sie es erwartet haben? Ich bezweifle, dass grepsich das Verhalten von in einem so wichtigen Punkt geändert hat.

echoübersetzt standardmäßig keine Escape-Sequenzen. -eDafür benötigen Sie das . Ähnlich verhält es sich mit der Shell. Sie müssen $'...'die Shell dazu bringen, Escape-Sequenzen zu verwenden.

verwandte Informationen