作为Linux的码农,每天都在命令行上码字,最烦的是要重复的键入很多命令,它们大同小异,大多只需些许修改。怎样高速寻找历史命令,加以修改为我所用呢?最近网上看到了fzf的模糊查找神器,又搜索了网上一些现有的方案,自己摸索了一个小工具。
主要功能:
- 利用命令行历史记录来对命令行、时间戳、当前节点名、目录名和其它用户的注释进行记录。
历史记录的显示是这个样子:
$history 10
296 [2019-10-12 17:32:45]dir # user’s comments here ### [ip-172-31-9-252:/data:]
297 [2019-10-12 17:33:07]aws s3 ls s3://variantcalling # important ### [ip-172-31-9-252:/data:]
298 [2019-10-12 17:33:41]this is a long-------------------test ### [ip-172-31-9-252:/data:]
300 [2019-10-12 17:34:36]cd # change director ### [ip-172-31-9-252:/data:==========]
301 [2019-10-12 17:34:55]dir ### [ip-172-31-9-252:/home2/lhc:]
`
- 用户可以通过在命令行中键入部分命令行,或是关键字(不一定是命令前半部分,只要是历史记录中有的词就好)选择命令集合;
- 用上下键激活fzf;
- 在fzf中可以二次选择模糊匹配,这一步支持关键字、键盘窗口或鼠标;
- 选择后的命令行重新放入提示符后面,自动去除了不必要的信息,只留代码段,简单编辑后即可使用。
下面是fzf的选择界面
安装方法:
0, Bash版本要求
要求bash 版本>=4.4.20;
注意MacOs默认版本较低,可以参考下面网址升级
Upgrading Bash on macOS
Linux升级要有系统管理员权限。
1,安装fzf;
fzf的官方网址提供了各种系统自然的安装方法,但我没有用,我是用conda安装的,大家根据自己的习惯就好。
2,配置~/.bashrc:
以下是代码加到后面即可
#>>>Maintain History Notebook>>>
# By Hongchao Lu ; luhongchao@gmail.com; Oct. 12, 2019
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000000
HISTFILESIZE=2000000
# set history time FORMAT
export HISTTIMEFORMAT="[%F %T]"
# See bash(1) for more options
HISTCONTROL="" # MUST set to NULL
HISTIGNORE="" # SHOUD set to NULL
# append to the history file, don't overwrite it
shopt -s histappend
# make sure the commands are all keeped into files
# https://stackoverflow.com/questions/945288/saving-current-directory-to-bash-history
# re-wrote from sript above
export oldHISTPWD=""
export oldHISTCMD=""
export HISTORY_COMMAND='hpwd=$(history 1); num=${hpwd//\[*/};let "num=${num// /}"; cmd=${hpwd//*]/} ;if [[ "X$oldHISTPWD" == "X$PWD" ]];then new_dir=""; else new_dir="==========";fi; hpwd=`printf "%-50s ### %s" "$cmd" [$HOSTNAME:$oldHISTPWD:$new_dir]`; oldHISTPWD=$PWD ; if [[ "X${oldHISTCMD// /}" == "X${cmd// /}" ]] ;then let "num_1=$num-1"; history -d $num_1; history -d $num_1; else history -d $num; fi ; oldHISTCMD=$cmd; history -s "$hpwd"'
export PROMPT_COMMAND="$HISTORY_COMMAND;$PROMPT_COMMAND"
#https://github.com/junegunn/fzf/wiki/examples#with-write-to-terminal-capabilities
# re-wrote the from script above
bind '"\e[A": "\C-r"'
bind '"\e[B": "\C-r"'
bind '"\C-r": "\C-x1\e^\e$\er"'
bind -x '"\C-x1": __fzf_history';
__fzf_history ()
{
__ehc $(history | grep "$READLINE_LINE" | fzf --tac --tiebreak=index | perl -ne 'm/^\s*([0-9]+)/ and print "!$1"')
}
__filter()
{
echo -e "$@" | sed 's/^ *//'| sed 's/\#\#\#.*$//'
}
__ehc()
{
if
[[ -n $1 ]]
then
bind '"\er": redraw-current-line'
bind '"\e^": magic-space'
bind -x '"\e$":READLINE_LINE=`__filter $READLINE_LINE`; READLINE_POINT=${#READLINE_LINE}'
READLINE_LINE=${1}
else
bind '"\er":'
bind '"\e^":'
bind '"\e$":'
fi
}
#<<<Maintain History Notebook<<<