Beliebt

Zsh behandelt einen String als Dateinamenmuster und beschwert sich dar├╝ber (Option NOMATCH) - zsh

Ich probiere Zsh aus und komme aus Bash. Ich hatte ein bisschen M├╝he zu verstehen, warum Zsh sich ├╝ber einen Grep-Regex beschwert.

[email protected] ~ % tty | grep ^/dev/tty[1-7]$ > /dev/null 2>&1
zsh: no matches found: ^/dev/tty[1-7]$

Ich habe festgestellt, dass die Ausgabe verschwindet und alles in Ordnung ist, wenn (1) ich den Regex in Anf├╝hrungszeichen setze, (2) die Schr├Ągstriche vom Regex entferne oder (3) verwende setopt NO_NOMATCH.

Aus dem Handbuch von zshoptions:

NOMATCH (+3) <C> <Z>

Wenn ein Muster f├╝r die Dateinamengenerierung keine ├ťbereinstimmungen aufweist, drucken Sie einen Fehler, anstatt ihn in der Argumentliste unver├Ąndert zu lassen. Dies gilt auch f├╝r die Dateierweiterung eines anf├Ąnglichen "~" oder "=".

Es scheint mir, dass der regul├Ąre Ausdruck aufgrund der Schr├Ągstriche als Dateinamenmuster behandelt wird. Ist das normal oder ein Fehler?

Es w├Ąre auch gro├čartig, wenn Sie etwas ├ähnliches wie die Seiten Bashism und BashPitfalls von GreyCat, aber f├╝r Zsh, h├Ątten. Kennen Sie eine solche Ressource?

Antworten:

1 f├╝r Antwort Ôäľ 1

Wenn Sie das eingestellt haben EXTENDED_GLOB Option, das Muster ^something wird zur Erzeugung von Dateinamen verwendet. Von dem zshexpn Manpage:

^x (Erfordert das Setzen von EXTENDED_GLOB.) Stimmt mit nichts au├čer ├╝berein das Muster x. Dies hat eine h├Âhere Priorit├Ąt als /, so ^foo/bar durchsucht Verzeichnisse in . au├čer ./foo f├╝r eine Datei mit dem Namen bar.

So, ^/dev/tty[1-7]$ versucht in jedem Unterverzeichnis zu finden (nichts ist ausgeschlossen, weil ^ wird direkt gefolgt von /) des aktuellen Verzeichnisses f├╝r eine Datei mit dem Namen dev/tty1$, dev/tty2$, ..., dev/tty7$ wie [1-7] stimmt mit genau einem Zeichen im Bereich zwischen 1 und 7 ├╝berein. $ wird in diesem Fall nicht besonders behandelt.

Du hast schon die L├Âsung gefunden, eingestellt NO_NOMATCH (mag gef├Ąhrlich sein, aber ich mag es sehr, da ich faul im Tippen bin ;)) oder Zitat (einfache oder doppelte Anf├╝hrungszeichen) das Caret.

Versuche es mit print Was ist los:

$ setopt nomatch extended_glob
$ echo ^/dev/tty[1-7]$
zsh: no matches found: ^/dev/tty[1-7]$

# ^ is doing filename generation in every sub-dir
$ touch foo/dev/tty5$
$ echo ^/dev/tty[1-7]$
foo/dev/tty5$

# quote to prevent filename generation
$ echo "^/dev/tty[1-7]$"
^/dev/tty[1-7]$
$ echo "^/dev/tty[1-7]$"
^/dev/tty[1-7]$

Ohne EXTENDED_GLOB gesetzt, wird das Caret buchst├Ąblich als normales Zeichen interpretiert. Also ist das Zitieren wieder dein Freund - diesmal nur der [1-7] L├Âst die Dateinamengenerierung aus:

$ setopt nomatch no_extended_glob
$ echo ^/dev/tty[1-7]$
zsh: no matches found: ^/dev/tty[1-7]$

# quote to prevent filename generation
$ echo ^/dev/tty"[1-7]"$
^/dev/tty[1-7]$

# caret is interpreted literally
$ mkdir ^/dev -p
$ touch ^/dev/tty5$
$ echo ^/dev/tty[1-7]$
^/dev/tty5$

Fazit: Das Zitieren von Regex-Mustern scheint mir immer eine gute Idee zu sein - obwohl ich normalerweise auch versuche, einige Tastenanschl├Ąge zu speichern.