zsh: wykluczanie plików ze wzoru

18

Powiedz, że mam następujące pliki:

|-- bar
`-- foo
    |-- type_A_1
    |-- type_A_2
    |-- type_B_1
    |-- type_B_2
    |-- type_B_xx
    |-- type_B_xx
    `-- something_else

Pomyślałem następującą komendę

print -l foo/*~{type_B*}

wypisuje wszystko poniżej foo oprócz rzeczy, które zaczynają się od, type_Bale nie, zamiast tego wypisuje wszystko pod foo:

foo/type_A_1
foo/type_A_2
foo/type_B_1
foo/type_B_2
foo/type_B_xx
foo/something_else

Próbowałem też print -l foo/*~type_Bi dostałem to samo.

Jak działa znak wieloznaczny wyjątku ~w Zsh?

Amelio Vazquez-Reina
źródło

Odpowiedzi:

10

Musisz dołączyć katalog do wyjątku: print -l foo/*~foo/type_A*lub print -l foo/*~{foo/type_A*}.

Jeśli chcesz, możesz zastąpić katalog symbolem wieloznacznym: print -l foo/*~*/type_A*

Jofel
źródło
Dzięki! Jeśli chodzi o drugi wzór, czy masz coś przeciwko wytłumaczeniu, jak foo/*~*/type_A*działa wzór ? Czy drugi *rozwija się do każdego folderu w katalogu roboczym, czy jest na tyle inteligentny, aby tylko rozwinąć foo?
Amelio Vazquez-Reina
@roseck Ponieważ wydaje się bardzo szybki (na przykład po uruchomieniu print *~**/*w /katalogu), zakładam, że najpierw rozwija on pierwszy wzorzec, a następnie usuwa wszystkie dopasowania pasujące do wzorca wykluczenia.
jofel
2
@roseck ~jest czysto tekstowy, część przed rozwinięciem ~rozwija się jak zawsze, a następnie część po usunięciu dopasowań. @Jofel Lepszym testem byłoby print /**/*~*: można zauważyć, że przemierza całe drzewo, nawet jeśli nic nie wydrukuje.
Gilles „SO- przestań być zły”
Myślałem, że chce wykluczyć typ_B, ale dołączyć typ_A.
systemovich,
Prawidłowa odpowiedź znajduje się poniżej
aryndin
30

zsh ma ^operatora globalnego, gdy EXTENDED_GLOB jest włączony. Wydaje się, że idealnie pasuje do podanej sytuacji:

setopt extendedglob
print -rl foo/^type_A*

Oznacza „dopasuj wszystko, z wyjątkiem tego, co pasuje do następującego wzoru”, ale jego działanie jest ograniczone do części wzoru między ukośnikami lub między początkiem wzoru a pierwszym ukośnikiem lub (jak w tym przypadku) między ostatnim cięcie i koniec wzoru.

Możesz wyświetlić zsh opcje aktualnie włączone za pomocą:

setopt

I wyłącz EXTENDED_GLOB za pomocą:

unsetopt extendedglob
Chris Johnsen
źródło