Come aggiungere un pattern al completamento della bash (per decomprimerlo)?


11

Quando scrivo

unzip <tab>

Ottengo un elenco di tutti i file che terminano .zip, che è il comportamento standard del completamento della scheda per il unzipcomando.

Tuttavia, voglio anche il completamento bash per i unzipfile di elenco che finiscono .udp, oltre ai .zipfile. Come posso ottenere questo comportamento nel mio locale .bashrc?

Risposte:


22

Invece di continuare a commentare ...


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

dovrebbe aggiungere il completamento per

-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

In altre parole: completa i file e rimuovi tutto ciò che non termina in .zipo .udp.


extra

Se si aggiunge -o defaultil completamento completerà / abbinare tutti i file e le directory se non v'è alcun file che terminano in .zipo .udp.

Se si aggiunge il -o plusdirscompletamento, verranno aggiunte eventuali directory oltre a tutte le corrispondenze di file che terminano con .zipo .udp.

attuale

Quando si utilizza complete -p unzipsi ottiene il modello corrente.

Dai tuoi commenti sembra principalmente che ti manchi +o @in uno schema, come in:

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

il che significherebbe abbinare qualsiasi file che termina letteralmente in.(zip|udp) . Per esempio

touch 'file_test.(zip|udp)'

Dai anche un'occhiata a questa sezione del manuale:

è possibile ad es. extglobnon è abilitato. Abilita da:

shopt -s extglob

Controlla lo stato corrente di tutte le shoptimpostazioni inserendo:

shopt

Funzione

In tal caso -F somethingsignifica che utilizza una funzione denominata qualcosa per generare l'elenco di completamenti.

In _filedir_xspecgenere è una funzione Debian. Potresti avere qualcosa del genere:

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

Il che significa /usr/share/bash-completion/bash_completionprocurarsi. Qui troverai la funzione in questione . Alcune righe più in basso si vede che questa funzione / completamento è aggiunta da una funzione chiamata _install_xspecad es .:

_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

Inserimenti manuali:


Aggiornamento ai commenti 1:

- Nessuna corrispondenza a causa di archivi o autorizzazioni di file non validi.

Ciò non dovrebbe influire sul risultato. completecorrisponde solo ai file forniti dalle regole e non esegue l'elaborazione dei file. Se riesci a elencarli con ls, dovrebbero corrispondere.

Come nota a margine, si potrebbe aggiungere tale funzionalità utilizzando una funzione completa:

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

- Colori. Perché si lsdistingue test.zipda test.upd?

Questo non influisce complete. I colori lssono forniti da $LS_COLORS. Provare:

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

Dovresti vedere qualcosa del genere *.zip=01;31che significa:

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

*.udp d'altra parte non ha alcuna voce associata, quindi nessuna colorazione.


Passaggio successivo (avrebbe dovuto essere il primo)

  1. Apri il terminale e vai a una directory con i file di test. Sia .zip che .udp
  2. accedere bash --norc
  3. accedere complete -f -X '!*.@(zip|udp)' unzip
  4. accedere shopt -s extglob
  5. accedere unzip <tab><tab>

Risultato?

Inoltre, fai clic su modifica sotto la domanda e aggiungi l'output di:

bind -V
shopt
env

potrebbe essere utile.


Grazie mille per la tua eccellente e lunga spiegazione, ma ancora non funziona. complete -p unzipproduce complete -f -X '!*.@(zip|udp)' unzipe unzip <tab>completa il file denominato test.zip. Tuttavia, la directory contiene anche un file denominato test.updche non si trova al completamento della scheda di unzip. Il fatto di autorizzazioni per file o una lunghezza zero del file può forse spiegare questo strano comportamento?
— Alex

@Alex: dovrebbe essere completato su file vuoti e validi, nonché su file in cui non si dispone dell'autorizzazione. È lo stesso comportamento se lo aggiungi a uno script di test? Ad esempio 1. alcuni script di test con set di esecuzione:, ~/bin/testing2. complete -f -X '!*.@(zip|udp)' testing, 3. testing <tab><tab>?
— Runium,

@Alex: Potresti anche aggiornare Q con l'output di shopt...
— Runium

extglobè attivato. L'esempio con "testing" seleziona di nuovo il zipfile. Ho notato che test.zipè mostrato in colore rosso, mentre test.updè mostrato in colore bianco con ls -l, entrambi i file sono vuoti con le stesse autorizzazioni, spostamento del proprietario e associazione di gruppo. Perché si lsdistingue test.zipda test.upd? Forse questo è un suggerimento per il problema che ho?
— Alex

@Alex: aggiunto un aggiornamento.
— Runium,

3

Nel file /etc/bash_completion, che presumibilmente stai acquistando da qualche parte, il completamento predefinito, almeno per la mia versione di bash(v4.2.25) è

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

Prova a cambiare l'intera espressione in

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

E aggiungi al tuo .bash_profile


Questo non risolve il mio problema. Se lo faccio e lo fonte, unzip <tab>non trova .zipné .updfile né altri file.
— Alex

Prova a premere due volte la scheda , vedi se è diverso. Gli altri completamenti funzionano come previsto? Ad esempio gzipcon i .gzfile?
— bsd

Colpire due volte la scheda non cambia nulla. Usando gunzipcon .gzi file selezionare i file solo che termina in .gz, ma la definizione è diverso: complete -F _filedir_xspec gunzip.
— Alex

Sorgi il file /etc/bash_completionnel tuo .bashrc?
— bsd

Provashopt -s extglob
— Edward Falk,

2

Prova ad aggiungere questa riga nel tuo .bashrc:

complete -f -o default -X '!*.+(zip|udp)' unzip

Sembra con questo suggerimento che troverò i .udpfile, ma solo se non .zipsono presenti file. Se un file test.zipe test.udpè presente nella directory corrente, unzip <tab>elenca solo il .zipfile. Mi aspetterei di vedere entrambi i file (cioè il completamento bash darebbe test.).
— Alex

Sei sicuro? Ho controllato su bash e mi sembra di trovare sia i file udpche i zipfile. Ti sei procurato .bashrcdopo aver aggiunto la riga?
— MK

Ho ripetuto in un nuovo terminale e ora unzip <tab>elenco tutti i file, anche quelli che terminano con una frase diversa. Ora piuttosto quello di cui ho bisogno.
— Alex,

Strano ... Sto eseguendo GNU bash versione 4.2.25 e funziona come previsto. Su quale versione di bash sei?
— MK

Potresti provare ad aggiungere due righe separate: complete -f -o default -X '!*.zip' unzipecomplete -f -o default -X '!*.udp' unzip
— mkc

1

Meglio usare _filedirinvece di "crudo" complete.

Giustificazione

  • grep _filedir -r $(pkg-config --variable=completionsdir bash-completion) | wc -l
  • i ~percorsi tilde ( ) vengono espansi
  • I prefissi vengono rimossi per le directory, ovvero per /home/tux/Do<TAB><TAB>l'elenco che si ottiene come risposta rimuove '/ home / tux' ed è quindi molto più compatto
  • Più facile da implementare e più fail-safe

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.