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 .zip.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.