Bash - pesquisa de histórico incremental (ctrl + r) - combinando várias palavras não adjacentes

4

Ao usar Ctrl + R para pesquisar o histórico bash, existe alguma maneira de combinar duas palavras que não são próximas umas das outras. Por exemplo, digamos que eu quisesse encontrar o último comando que continha httpd e awk , mas não ao lado um do outro. Existe alguma opção melhor do que recorrer ao grepping do histórico bash para combinar com ambos ou pressionar Ctrl + R para percorrer as entradas correspondentes a uma palavra-chave até que o comando desejado seja encontrado?

    
por sa289 14.06.2015 / 03:54

2 respostas

2

Manual de referência do Bash diz :

Readline provides commands for searching through the command history for lines containing a specified string

Você quer um regexp em vez de uma string fixa.

Tente hstr :
1. Instalação
2. Configuração

Você deve ver algo assim com hstr :

Atualizar:
Outraferramentaé fzf .

  1. Instalar : git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf && ~/.fzf/install

  2. Reenvie sua ~/.bashrc : source ~/.bashrc

Você deve ver algo assim com fzf :

    
por 30.06.2015 / 08:17
2

Eu não conheço nenhuma maneira interna de fazer isso, mas você pode escrever uma pequena função para fazer o grep e editar seu arquivo de histórico para que os resultados apareçam no final, e então você pode facilmente escolher um dos arquivos. corresponde apenas avançando pela nova história. (Isso altera a ordem dos comandos no seu histórico).

Aqui está essa função. Eu estou supondo que você quer encontrar as 2 (ou mais) palavras, não importa em qual ordem elas aparecem. Você pode definir o número máximo de correspondências que deseja aceitar; aqui está 10. Eu também estou assumindo que o grep inicial não retorna uma string humungous, ou você precisará usar arquivos temporários ao invés de strings bash.

hist(){
    local maxmatches=10 word=$1 matches new nummatches
    shift
    history -w # write out history to HISTFILE
    matches=$(grep -e "$word" $HISTFILE)
    for word
    do   new=$(echo "$matches" | grep -e "$word")  || return # if str too big
         matches=$new
    done
    nummatches=$(echo "$matches" | wc -l)
    echo "$nummatches matches"
    if [ $nummatches -gt 0 -a $nummatches -le $maxmatches ]
    then echo "$matches" >>$HISTFILE # add matches to end of file
         history -c # clear history
         history -r # read history from file
         history $nummatches # show last few lines
    else echo "zero or too many matches. (max $maxmatches)"
    fi
}

Se você não quiser a correspondência de padrões regulares para suas palavras, use fgrep em vez de grep. Se você quer apenas a ordem dada, use uma única palavra como "httpd. * Awk". Você também pode remover o loop for se usar apenas uma palavra dessa maneira.

    
por 14.06.2015 / 14:28