Unterschied zwischen * und? * Glob in Bash

9
  • * ist ungefähr ein Platzhalter mit einer unbegrenzten Länge.
  • ? ist ungefähr ein Platzhalterzeichen für eine oder eine Länge von eins.

Gibt es einen Unterschied zwischen der Verwendung von *vs ?*bei der Suche nach Zeichenfolgen in bash?

TrevorKS
quelle
5
Im Zusammenhang mit Globbing oder Regex?
llua
1
Ich denke, dies ist eine globale Frage, keine Frage mit regulären Ausdrücken. In diesem Fall sollten sich die Tags ändern. Wenn es stattdessen / auch um reguläre Bash-Ausdrücke geht, sollte sich der Text ändern, um zu sagen, worum es wirklich geht. Es sieht so aus, als ob das Tag für reguläre Ausdrücke in der Bearbeitung von jemandem hinzugefügt wurde, also nehme ich an, dass dies der falsche Teil ist.
Michael Homer
1
Ich habe entsprechend bearbeitet, aber bitte zurücksetzen und bearbeiten , um zu sagen, was Sie wollten, wenn ich das falsch verstanden habe. Es gibt Verwirrung, weil "Eins oder Null" eine Regex-Sache ist, aber ?*keine nützliche Sache, um in einem regulären Ausdruck zu schreiben.
Michael Homer
Können Sie ein Beispiel für diese "Suche nach Zeichenfolgen in Bash" zeigen? Dies kann im Übrigen eine Bash sein, wenn Sie grepmit einem regulären Ausdruck, findeinem Dateinamenmuster oder als Platzhalter ausgeführt werden.
Jeff Schaller

Antworten:

17

Der Unterschied besteht darin, dass in bash(während Sie die Frage markiert haben) *mit einer Zeichenfolge mit einer Länge von null oder mehr Zeichen ?*übereinstimmt , während mit einer Zeichenfolge mit mindestens 1 Zeichen übereinstimmt. Betrachten Sie zum Beispiel zwei Dateien: file.txtund xfile.txtund versuchen Sie, sie mit ls ?*file.txtoder aufzulisten ls *file.txt.

Ein reales Szenario, wenn ich ein solches Konstrukt verwende, ist das Auflisten versteckter Dateien. Sehr oft mache ich es einfach

ls .??*

Doppelte Fragezeichen verhindern hier das Auflisten des aktuellen Verzeichnisses .und des übergeordneten Verzeichnisses .., wie dies bei einer einfacheren Form der Fall wäre ls .*.


Ich muss hier darauf hinweisen, dass mein .??*nicht perfekt ist; Beispielsweise .fstimmen Dateinamen mit nur zwei Zeichen nicht mit diesem Muster überein. Eine zuverlässigere Lösung ist ls {..?,.[!.]}*, aber normalerweise ist das zu viel für mich zum Tippen.

jimmij
quelle
find /home/?*/.[!.‹?* -maxdepth 0 -perm / g + wx, o + rwx -exec chmod g-wx, o-rwx '{}' +
TrevorKS
Das ist der Befehl, der mich zu dieser Frage geführt hat, dieselbe Strategie, die zur Vermeidung des aktuellen und des übergeordneten Verzeichnisses verfolgt wurde.
TrevorKS
1
Nur zu Ihrer Information, wenn Sie GNU-Coreutils verwenden (und Sie sind es wahrscheinlich), können Sie einfach übergeben -a, lsum alle Dateien oder -Aalle Dateien außer .und anzuzeigen ...
Jonathan Callen
@JonathanCallen Ja natürlich, aber für andere Befehle , die nicht immer der Fall ist, wie zum Beispiel der Größe der Dot-Dateien überprüft du -scm .??*vs du -scm .*.
Jimmyij
.??*wird auch Dateien wie vermissen .x. Am besten ist es, eine Muschel wie pdksh, mksh, zsh oder fish zu verwenden, die niemals .oder ..in ihren Glob-Erweiterungen enthalten ist. Oder in ksh93, eingestellt FIGNOREauf @(.|..)(obwohl das die Nebenwirkung von nicht mehr versteckt dot-Dateien hat). In anderen Shells benötigen Sie .[!.]* .??*(oder .[^.]* .??*in einigen Shells, die in csh / tcsh ausgenommen sind, erhalten Sie wahrscheinlich einen Fehler (von ls), wenn einer der Globs nicht übereinstimmt (wahrscheinlich der erste).
Stéphane Chazelas
7

Woher haben Sie diese Definition, auf welche Art von Ausdruck beziehen Sie sich?

Wenn wir über Shell-Ausdrücke sprechen, können beide Zeichen alleine verwendet werden, aber die Definition für ?stimmt nicht überein, da sie dann immer mit einem Zeichen und nicht mit eins oder null übereinstimmt.

Wenn wir über reguläre Ausdrücke sprechen, sind beide Operatoren, die nach einem Ausdruck stehen. Also müsste in "? *" Nach etwas anderem gesetzt werden.

RalfFriedl
quelle