Como criar uma frase expansível especial no bash?

12

Eu me vejo fazendo <command> --help | grep <feature> muito frequentemente todos os dias. Eu queria saber se era possível fazer algo como ^^ que se expande para "--help | grep" e então eu faço isso:

ls ^^ size

Isso executaria o seguinte:

ls --help | grep size
    
por yukashima huksay 11.01.2018 / 06:28

5 respostas

17

Você pode usar uma função bash para isso:

Coloque o seguinte em seu ~ / .bashrc:

qh() {
    type -all "$1" ; { man "$1" || "$1" --help ;} | egrep -i -- "$2"
}

Quando você salvar seu bashrc do source ~/.bashrc , poderá fazer:

$ qh ls size
      --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                               '--block-size=M' prints sizes in units of
  -h, --human-readable       with -l and/or -s, print human readable sizes
  -s, --size                 print the allocated size of each file, in blocks
  -S                         sort by file size, largest first
      --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
  -T, --tabsize=COLS         assume tab stops at each COLS instead of 8
    
por 11.01.2018 / 06:31
15

Com zsh , você usaria um alias global :

$ alias -g '^^=--help|grep --color -i'
$ ls ^^ size
     --block-size=SIZE      scale sizes by SIZE before printing them; e.g.,
                              '--block-size=M' prints sizes in units of
                              1,048,576 bytes; see SIZE format below
 -h, --human-readable       with -l and/or -s, print human readable sizes
 -s, --size                 print the allocated size of each file, in blocks
 -S                         sort by file size, largest first
     --sort=WORD            sort by WORD instead of name: none (-U), size (-S),
 -T, --tabsize=COLS         assume tab stops at each COLS instead of 8
The SIZE argument is an integer and optional unit (example: 10K is 10*1024)

Com bash , você pode usar expansão de histórico , o que acontece cedo o suficiente na análise de sintaxe do shell e pode funcionar substituindo um pipe:

  1. Prepare o histórico com o texto que você deseja substituir e um caractere especial que você provavelmente não usaria (como £ aqui que está no meu teclado):

     $ --help $(: £)|grep
     bash: --help: command not found
     Usage: grep [OPTION]... PATTERN [FILE]...
     Try 'grep --help' for more information.
    
  2. Em seguida, usando a expansão do histórico para recuperar isso:

    $ ls !?£? size
    ls --help $(: £)|grep size
         --block-size=SIZE  scale sizes by SIZE before printing them; e.g.,
                              '--block-size=M' prints sizes in units of
     -h, --human-readable   with -l and/or -s, print human readable sizes
     -s, --size             print the allocated size of each file, in blocks
     -S                     sort by file size, largest first
         --sort=WORD        sort by WORD instead of name: none (-U), size (-S),
     -T, --tabsize=COLS     assume tab stops at each COLS instead of 8
    

Ou você pode ter readline expand --help|grep em alguma tecla ou sequência de teclas. Para que isso se aplique apenas a bash (e não a outros aplicativos como gdb usando readline), é possível usar o comando bind bash builtin que é a API bash para configurar readline , por exemplo, em seu ~/.bashrc :

bind '"^^": "--help|grep "'

Ou adicione ao seu ~/.inputrc (arquivo de configuração da linha de leitura):

$if Bash
"^^": "--help|grep "
$endif

(há outros shells como rc ou es que usam readline e onde fazer essa ligação pode fazer sentido, mas AFAICT, eles não definem a variável rl_readline_name antes de invocar readline para que você não seja capaz de adicionar alguns $if declarações para eles (eles seriam mostrados como other como todos os aplicativos que usam readline sem dizer seu nome de aplicativo)).

Note que você precisa inserir o segundo ^ dentro de meio segundo (por padrão) após o primeiro para a substituição ocorrer.

    
por 11.01.2018 / 08:06
8

Você pode usar ligações de linha de leitura:

adicione uma linha como

"^^": "--help | grep "

para o seu ~ / .inputrc

Em seguida, pressione ^ X ^ R no seu termo e a ligação será ativada.

A codificação ls ^^ resultará agora em ls --help | grep .

    
por 11.01.2018 / 09:34
5

Usando less para exibir a mensagem de ajuda

Você pode achar útil ver o contexto das linhas que correspondem à sua consulta de pesquisa.

hh () { "${1}" --help | less -p "${2}" ; }

A sintaxe para chamar essa função bash é semelhante à resposta da função qh in @ tgwtdt, com o primeiro argumento sendo o comando a ser examinado e o segundo argumento sendo o termo de pesquisa. Por exemplo:

hh ls size
hh ls "symbolic link"

Isso abre a mensagem de ajuda completa em less , destaca todas as ocorrências do termo de pesquisa e rola para a primeira instância do termo de pesquisa. Em seguida, você pode pressionar n para avançar até a próxima linha que contém o termo de pesquisa, n novamente para o próximo e assim por diante. Para rolar de volta para uma instância anterior, pressione N . Use as chaves Home , End , Page Up , Page Down , Up Arrow e Down Arrow para navegação geral. Pressione q ou Q para sair de less e retornar para a linha de comando.

    
por 12.01.2018 / 04:15
3

Gostei da solução do @tgwtdt, então aprimorei um pouco.

Isso faz a mesma coisa, mas faz um pouco para manipular erros e também tenta processar internos.

qh usa () ao invés de {} então qh1 () e out são locais (em uma subshell).

function qh () (
    function qh1 () {
      out="$(help "$1" 2>&1 )"
      [ $? -ne 0 ] && return 1
      echo "$out"
    }

    type -all "$1" ; { qh1 "$1" || "$1" --help 2>/dev/null || man "$1" 2>/dev/null ;} | egrep -i -- "$2"
) 
    
por 13.01.2018 / 08:38