Jak dodać wzorzec do zakończenia bash (do rozpakowania)?

12

Kiedy piszę

unzip <tab>

Otrzymuję listę wszystkich plików kończących się na .zip, co jest standardowym zachowaniem uzupełniania tabulacji dla unzippolecenia.

Jednak chcę także uzupełnienia bash dla unzipplików list, które kończą się .udp, oprócz .zipplików. Jak mogę uzyskać takie zachowanie w moim lokalnym .bashrc?

Alex
źródło

Odpowiedzi:

23

Zamiast komentować…


complete -f -X '!*.@(zip|udp)' unzip

należy dodać uzupełnienie dla

-f -X '!*.@(zip|udp)'
 |  |  | |||________|
 |  |  | ||     |
 |  |  | ||     +- filterpat: zip or udp
 |  |  | |+-------------  @ : Matches one of the given patterns
 |  |  | +-------------- *. : Anything+<dot>
 |  |  +----------------  ! : Negate
 |  +------------------- -X : Filter out matches in "filterpat"
 +---------------------- -f : files

Innymi słowy: Uzupełnij pliki i usuń wszystkie nie kończące się na .ziplub .udp.


Dodatki

Jeśli dodasz -o defaultuzupełnianie, uzupełni / dopasuje wszystkie pliki i katalogi, jeśli nie ma plików kończących się na .ziplub .udp.

Jeśli dodasz -o plusdirsuzupełnienie, dodasz dowolne katalogi oprócz dopasowań plików kończących się na .ziplub .udp.

obecny

Po użyciu complete -p unzipotrzymasz aktualny wzór.

Z twoich komentarzach brzmi prawie identycznie jak brakuje albo +czy @w strukturze, jak w:

# Err:
complete -f -X '!*.(zip|udp)' unzip
                   |
                   +---- Missing + or @

co oznaczałoby dopasowanie dowolnego pliku dosłownie kończącego się na.(zip|udp) . Na przykład

touch 'file_test.(zip|udp)'

Zobacz także tę sekcję instrukcji:

jest to możliwe, np. extglobnie jest włączone. Włącz przez:

shopt -s extglob

Sprawdź aktualny stan wszystkich shoptustawień, wprowadzając:

shopt

Funkcjonować

Jeśli tak -F something, oznacza to, że używa funkcji o nazwie coś do wygenerowania listy uzupełnień.

_filedir_xspecJest zwykle funkcją Debianie. Możesz mieć coś takiego:

$ cat /etc/bash_completion
. /usr/share/bash-completion/bash_completion

Co oznacza /usr/share/bash-completion/bash_completionpozyskiwać. Tutaj znajdziesz omawianą funkcję . Kilka linii dalej widać, że ta funkcja / uzupełnienie jest dodawana przez funkcję o nazwie _install_xspecnp .:

_install_xspec '!*.@(zip|[ejsw]ar|exe|pk3|wsz|zargo|xpi|s[tx][cdiw]|sx[gm]|o[dt][tspgfc]|od[bm]|oxt|epub|apk|do[ct][xm]|p[op]t[mx]|xl[st][xm])' unzip zipinfo

Wpisy ręczne:


Zaktualizuj komentarze 1:

- Brak zgodności z powodu nieprawidłowych archiwów lub uprawnień do plików.

Nie powinno to wpłynąć na wynik. completepasuje tylko do plików określonych przez reguły i nie przetwarza plików. Jeśli możesz je wymienić ls, powinny się zgadzać.

Na marginesie można dodać taką funkcjonalność za pomocą pełnej funkcji:

function _unzip_validated() {
    # 1. Generate list of files ending in e.g. .zip and .udp
    # 2. Validate each file and remove invalid ones from file list.
}

complete -F _unzip_validated unzip

- kolory. Dlaczego lsodróżnić test.zipod test.upd?

To nie ma wpływu complete. Kolory według lssą dostarczane przez $LS_COLORS. Próbować:

echo "$LS_COLORS" | tr : '\n' | sort

Powinieneś zobaczyć coś takiego, *.zip=01;31co oznacza:

*.zip=01;31
|____| |  |
   |   |  +--- Red
   |   +------ Bold
   +---------- Files with .zip extension

*.udp z drugiej strony nie ma z nim żadnego wpisu, więc nie ma koloru.


Następny krok (powinien być pierwszy)

  1. Otwórz terminal i przejdź do katalogu z plikami testowymi. Zarówno .zip, jak i .udp
  2. Wchodzić bash --norc
  3. Wchodzić complete -f -X '!*.@(zip|udp)' unzip
  4. Wchodzić shopt -s extglob
  5. Wchodzić unzip <tab><tab>

Wynik?

Ponadto kliknij edytuj poniżej pytania i dodaj wynik:

bind -V
shopt
env

może być pomocny.

Runium
źródło
Bardzo dziękuję za twoje doskonałe i długie wyjaśnienie, ale nadal nie działa. complete -p unzipdaje complete -f -X '!*.@(zip|udp)' unzipi unzip <tab>uzupełnia plik o nazwie test.zip. Jednak katalog zawiera również plik o nazwie, test.updktórego nie można znaleźć po uzupełnieniu tabulatorem unzip. Czy fakt uprawnień do pliku lub zerowa długość pliku może tłumaczyć to dziwne zachowanie?
Alex
@Alex: Powinien zostać ukończony zarówno dla pustych, jak i prawidłowych plików, a także dla plików, do których nie masz uprawnień. Czy to samo zachowanie dodaje się do skryptu testowego? Np. 1. jakiś skrypt testowy z zestawem wykonawczym:, ~/bin/testing2. complete -f -X '!*.@(zip|udp)' testing, 3. testing <tab><tab>?
Runium
@Alex: Możesz także zaktualizować Q z wyjściem shopt
Runium
extglobjest aktywowany. Przykład z „testowaniem” wybiera zipplik tylko ponownie. Zauważam, że test.zipjest wyświetlany w kolorze czerwonym, podczas gdy test.updw kolorze białym ls -l, oba pliki są puste z tymi samymi uprawnieniami, zmiana właściciela i powiązanie grupy. Dlaczego lsodróżnić test.zipod test.upd? Może to wskazówka na temat mojego problemu?
Alex
@Alex: Dodano aktualizację.
Runium
3

W pliku /etc/bash_completion, który prawdopodobnie gdzieś pozyskujesz, domyślnym uzupełnieniem, przynajmniej dla mojej wersji bash(v4.2.25), jest

complete -f -X '!*.@(zip|[ejw]ar|exe|pk3|wsz|zargo|xpi|sxw|o[tx]t|od[fgpst]|epub|apk)' unzip zipinfo

Spróbuj zmienić całe wyrażenie na

complete -f -X '!*.@(zip|[ejw]ar|exe|pk3|wsz|zargo|xpi|sxw|o[tx]t|od[fgpst]|epub|apk|udp)' unzip zipinfo

I dodaj do swojego .bash_profile

bsd
źródło
To nie rozwiązuje mojego problemu. Jeśli to zrobię i źródło, unzip <tab>nie znajdzie .zipani .updplików, ani innych plików.
Alex
Spróbuj dwukrotnie nacisnąć kartę , aby sprawdzić, czy to coś innego. Czy inne uzupełnienia działają zgodnie z oczekiwaniami? Na przykład gzipz .gzplikami?
bsd
Dwukrotne naciśnięcie karty nic nie zmienia. Korzystanie gunzipz .gzplików wybrać pliki tylko kończy się .gz, ale definicja jest również inna: complete -F _filedir_xspec gunzip.
Alex
Czy plik źródłowy znajduje się /etc/bash_completionw Twoim pliku .bashrc?
bsd
Spróbujshopt -s extglob
Edward Falk,
2

Spróbuj dodać ten wiersz do swojego .bashrc:

complete -f -o default -X '!*.+(zip|udp)' unzip
mkc
źródło
Wydaje się, że z tą sugestią znajdę .udppliki, ale tylko wtedy, gdy nie ma żadnych .zipplików. Jeśli plik test.zipa test.udpznajduje się w bieżącym katalogu, unzip <tab>wyświetla tylko .zipplik. Spodziewałbym się zobaczyć oba pliki (tzn. Dałoby to zakończenie bash test.).
Alex
Jesteś pewny? Sprawdziłem moją bash i wydaje mi się, że znajduję zarówno pliki, jak udpi zippliki. Czy źródło .bashrcpo dodaniu linii?
mkc
Powtórzyłem w nowym terminalu i teraz unzip <tab>wypisuję wszystkie pliki, nawet te, które kończą się inną frazą. Teraz to, czego potrzebuję.
Alex
Dziwne .. Używam GNU bash w wersji 4.2.25 i działa zgodnie z oczekiwaniami. W której wersji bash korzystasz?
mkc
Czy możesz spróbować dodać dwie osobne linie: complete -f -o default -X '!*.zip' unzipicomplete -f -o default -X '!*.udp' unzip
mkc
1

Lepsze użycie _filedirzamiast „surowego” complete.

Usprawiedliwienie

  • grep _filedir -r $(pkg-config --variable=completionsdir bash-completion) | wc -l
  • ~Ścieżki tilde ( ) są rozwijane
  • Prefiksy są usuwane dla katalogów, tj. Dla /home/tux/Do<TAB><TAB>listy, którą otrzymujesz w odpowiedzi, usuwa „/ home / tux”, a zatem jest znacznie bardziej kompaktowy
  • Łatwiejszy do wdrożenia i bardziej bezpieczny w razie awarii

MWE

_unzip_completor()
{
    # init bash-completion's stuff
    _init_completion || return

    # fill COMPREPLY using bash-completion's routine
    _filedir '@(zip|udp)'
}
complete -F _unzip_completor unzip
Johannes
źródło