Was bedeutet. ?? * in einem Shell-Befehl?


22

Der folgende Befehl tar"punktiert" alle Dateien und Ordner:

tar -zcvf dotfiles.tar.gz .??*

Ich kenne mich mit regulären Ausdrücken aus , verstehe aber nicht, wie man sie interpretiert .??*. Ich habe ls .??*und ausgeführt und mir tree .??*die aufgelisteten Dateien angesehen. Warum enthält dieser reguläre Ausdruck alle Dateien in Ordnern, die .beispielsweise mit beginnen?


Antworten:


32

Globs sind keine regulären Ausdrücke. Im Allgemeinen versucht die Shell, alle Eingaben in der Befehlszeile zu interpretieren, die Sie nicht als Glob angeben. Shells müssen überhaupt keine regulären Ausdrücke unterstützen (obwohl es in Wirklichkeit viele der schickeren, moderneren tun, z. B. die=~ Regex-Match-Operator im bash [[Konstrukt).

Das .??*ist ein Glob. Es stimmt mit jedem Dateinamen überein, der mit einem wörtlichen Punkt beginnt ., gefolgt von zwei beliebigen (nicht unbedingt gleichen) Zeichen.?? , gefolgt vom Äquivalent des regulären Ausdrucks von [^/]*, dh 0 oder mehr Zeichen, die keine sind /.

Ausführliche Informationen zur Erweiterung des Shell-Pfadnamens (vollständiger Name für "Globbing") finden Sie in der POSIX-Spezifikation .


10
Zusätzlicher Punkt: Dies ist ein Versuch, ein Glob zu schreiben, das mit allen Punktedateien in einem Verzeichnis außer den speziellen Einträgen übereinstimmt .und ..mit dem man normalerweise nichts anfangen möchte. Es ist nicht ganz richtig; Es wird nichts mit dem Namen ' .X' aufgenommen, wobei X ein anderes Zeichen als ein Punkt ist. Ich glaube nicht, dass es möglich ist, ein einzelnes Glob zu schreiben, das zu jeder Punktdatei passt, außer .und .., aber Sie können es mit zwei machen: tar zcvf dotfiles.tar.gz .[!.] .??*zum Beispiel.
zwol

@Zack: Danke für die Klarstellung. Ich habe einen Kommentar dazu gepostet, ihn dann aber gelöscht. ls .?Es wurde das Gleiche wie zurückgegeben ls .., was bedeutete, dass sich keine anderen Einträge in dem Ordner befanden, die dem Muster entsprachen .?. Ich hätte .[^.]für alle .?anderen Dateien als getan ...
SabreWolfy

2
@SabreWolfy Wenn Sie die POSIX-Spezifikation sorgfältig lesen, ist das eigentlich ein wichtiger Unterschied zwischen Globs und Regex: In Klammerausdrücken [^abc]bedeutet die Regex-Syntax dasselbe wie [!abc]in der Glob-Syntax (dh ^wird durch !für Globs ersetzt). Die Verwendung der [^abc]Stilsyntax in einem Glob ist nicht sehr portabel, da POSIX nicht ^genau angibt, was es bedeutet. Einige Shells interpretieren sie daher mit einer regulären Semantik, während andere sie nur als Literalzeichen behandeln .
JW013

1
@ jw013: Danke für die Details. Ich muss mich daran erinnern, dass glob! = Regexp :)
SabreWolfy

1
Mir ist gerade in den Sinn gekommen, dass .[!.]es tarim allgemeinen Fall, dass es keine Dateien gibt, die mit diesem Muster übereinstimmen, ein Literal in der Befehlszeile geben kann. Mit einigen Shells können Sie dieses Verhalten steuern, z. B. mit Bash, shopt -s nullglobund es wird in der Befehlszeile ausgeblendet, wenn es nicht mit irgendetwas übereinstimmt. Dies ist jedoch keine universelle Funktion.
zwol

8

Der .??*Platzhalter ( kein regulärer Ausdruck, obwohl er so aussieht) wird in Dateinamen übersetzt, die mit einem Punkt ( .) beginnen, gefolgt von zwei einzelnen Zeichen (?? ) und einer beliebigen Anzahl (null oder mehr) anderer Zeichen ( *).

Vielleicht ist diese Seite über Platzhalter in Dateinamen hilfreich.


-1

Um die anderen Antworten zu ergänzen, wird eine einzelne ?Datei in einen einzelnen Zeichendateinamen übersetzt und ??mit Dateinamen abgeglichen, die nur aus zwei Zeichen bestehen.

[root@mercy testdir_2]# ls
ion  it  r
[root@mercy  testdir_2]# ls ?
r
[root@mercy  testdir_2]# ls ??
it
[root@mercy 1 testdir_2]# ls ???
ion
[root@mercy  testdir_2]#

Downvoter, könntest du bitte einen Kommentar abgeben? Würde mich freuen, korrigiert zu werden, wenn ich mich irre.
Sree

Ihre Antwort hat die Frage nicht vollständig beantwortet.
SabreWolfy
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.