Co oznacza. ?? * w poleceniu powłoki?

22

Następujące polecenie będzie tarwszystkie pliki i foldery „kropka”:

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

Znam wyrażenia regularne , ale nie rozumiem, jak interpretować .??*. Wykonałem ls .??*i tree .??*spojrzałem na pliki, które były na liście. Dlaczego to wyrażenie regularne obejmuje .na przykład wszystkie pliki w folderach zaczynające się od?

SabreWolfy
źródło

Odpowiedzi:

32

Globs nie są wyrażeniami regularnymi. Ogólnie rzecz biorąc, powłoka spróbuje zinterpretować wszystko, co wpiszesz w wierszu poleceń, którego nie podajesz jako glob. Powłoki nie są wcale wymagane do obsługi wyrażeń regularnych (chociaż w rzeczywistości robi to wiele bardziej wymyślnych, bardziej nowoczesnych, np. =~Operator dopasowania wyrażenia regularnego w bash [[konstrukcji).

To .??*jest glob. Pasuje do każdej nazwy pliku, która zaczyna się od literalnej kropki ., po której następują dowolne dwa (niekoniecznie takie same) znaki ??, po których następuje równoważnik wyrażenia regularnego [^/]*, tj. 0 lub więcej znaków, które nie są /.

Aby uzyskać szczegółowe informacje na temat rozszerzenia nazwy ścieżki powłoki (pełna nazwa „globbing”), zobacz specyfikację POSIX .

jw013
źródło
10
Dodatkowa uwaga: jest to próba napisania globu, który pasuje do wszystkich plików dotfiles w katalogu z wyjątkiem pozycji specjalnych .i z ..którymi zwykle nie chce się nic robić. To nie do końca prawda; nie odbiera niczego o nazwie „ .X”, gdzie X jest postacią inną niż kropka. Nie sądzę, że można napisać jedną glob, która pasuje do każdego pliku kropki oprócz .i .., ale można to zrobić za pomocą dwóch: tar zcvf dotfiles.tar.gz .[!.] .??*na przykład.
zwolnienie
@Zack: Dzięki za wyjaśnienie. Opublikowałem komentarz na ten temat, ale potem go usunąłem. ls .?zwrócił to samo co ls .., co oznaczało, że w folderze nie ma innych wpisów pasujących do wzorca .?. Zrobiłbym .[^.]dla wszystkich .?plików innych niż ...
SabreWolfy,
2
@SabreWolfy Jeśli dokładnie przeczytałeś specyfikację POSIX, to tak naprawdę ważna różnica między globs a regex: w wyrażeniach nawiasowych, [^abc]w składni regex oznacza to samo, co [!abc]w składni glob (tzn. ^Jest zastępowane przez !dla globs). Używanie [^abc]składni stylu w glob nie jest zbyt przenośne, ponieważ POSIX nie określa, co to znaczy, więc niektóre powłoki interpretują go za pomocą semantyki przypominającej wyrażenia regularne, podczas gdy inne traktują ^tylko jako dosłowny znak.
jw013,
1
@ jw013: Dzięki za szczegóły. Muszę pamiętać, że glob! = Regexp :)
SabreWolfy
1
Właśnie przyszło mi do głowy, że .[!.]może to być literał w tarwierszu poleceń w typowym przypadku, gdy nie ma plików pasujących do tego wzorca. Niektóre powłoki pozwalają kontrolować to zachowanie, np. Za pomocą bash, shopt -s nullglobsprawi, że zniknie z linii poleceń, jeśli nic nie pasuje, ale nie jest to cecha uniwersalna.
zwolnienie
8

Symbol .??*wieloznaczny ( nie wyrażenie regularne, choć tak to wygląda) tłumaczy się na nazwy plików rozpoczynające się od kropki ( .), po której następują dwa pojedyncze znaki ( ??), a następnie dowolna liczba (zero lub więcej) innych znaków ( *).

Może ta strona na symbolach wieloznacznych w nazwach plików będzie pomocna.

Levon
źródło
-1

Aby dodać do innych odpowiedzi, pojedynczy ?tłumaczy na nazwę pliku o jednym znaku i ??dopasowuje nazwy plików, które mają tylko dwa znaki i tak dalej.

[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]#
Sree
źródło
Downvoter, czy mógłbyś komentować? Byłbym szczęśliwy, gdyby ktoś się mylił.
Sree
Twoja odpowiedź nie odpowiedziała w pełni na pytanie.
SabreWolfy,