cwd*_*cwd 82 command-line bash command-history sort uniq
我真的很喜欢使用control+r
递归搜索我的命令历史记录。我发现了一些我喜欢与它一起使用的好选择:
# ignore duplicate commands, ignore commands starting with a space
export HISTCONTROL=erasedups:ignorespace
# keep the last 5000 entries
export HISTSIZE=5000
# append to the history instead of overwriting (good for multiple connections)
shopt -s histappend
Run Code Online (Sandbox Code Playgroud)
对我来说唯一的问题是erasedups
只删除连续的重复项 - 所以使用这串命令:
ls
cd ~
ls
Run Code Online (Sandbox Code Playgroud)
该ls
命令实际上将被记录两次。我想过定期使用 cron 运行:
cat .bash_history | sort | uniq > temp.txt
mv temp.txt .bash_history
Run Code Online (Sandbox Code Playgroud)
这将实现删除重复项,但不幸的是顺序不会被保留。如果我不先sort
处理文件,我不相信uniq
可以正常工作。
如何删除 .bash_history 中的重复项,保留顺序?
.bash_history
通过脚本覆盖文件有什么问题吗?例如,如果您删除了一个 apache 日志文件,我认为您需要发送一个 nohup / reset 信号kill
以使其刷新它与文件的连接。如果.bash_history
文件是这种情况,也许我可以用某种方式ps
来检查并确保在运行过滤脚本之前没有连接的会话?
小智 71
因此,在被重复项惹恼后,我一直在寻找完全相同的东西,并发现如果我编辑我的~/.bash_profile
或我~/.bashrc
的:
export HISTCONTROL=ignoreboth:erasedups
Run Code Online (Sandbox Code Playgroud)
它完全符合您的要求,它只保留最新的任何命令。ignoreboth
实际上就像做一样,ignorespace:ignoredups
并且erasedups
完成工作。
至少在我使用 bash 的 Mac 终端上,这项工作很完美。在 askubuntu.com 上找到它。
wnr*_*rph 41
此命令的工作方式类似于sort|uniq
,但将线条保持在原位
nl|sort -k 2|uniq -f 1|sort -n|cut -f 2
Run Code Online (Sandbox Code Playgroud)
基本上,在每一行前面加上它的编号。sort|uniq
-ing之后,所有行都根据它们的原始顺序(使用行号字段)重新排序,并且行号字段从行中删除。
这个解决方案有一个缺陷,即未定义一类相等线的哪个代表将使其在输出中,因此它在最终输出中的位置是未定义的。但是,如果应该选择最新的代表,您可以sort
通过第二个键输入:
nl|sort -k2 -k 1,1nr|uniq -f1|sort -n|cut -f2
Run Code Online (Sandbox Code Playgroud)
对于重读和写回历史,您可以分别使用history -a
和history -w
。
Cla*_*ley 28
在野外找到了这个解决方案并进行了测试:
awk '!x[$0]++'
Run Code Online (Sandbox Code Playgroud)
第一次看到一行的特定值 ($0) 时,x[$0] 的值为零。
零的值被反转!
并变为一。
计算结果为 1 的语句会导致默认操作,即打印。
因此,第一次$0
看到特定内容时,就会打印出来。
每次(重复) 的值x[$0]
都会增加,
其否定值为零,并且不会打印计算结果为零的语句。
要保留最后一个重复值,请反转历史并使用相同的 awk:
awk '!x[$0]++' ~/.bash_history # keep the first value repeated.
tac ~/.bash_history | awk '!x[$0]++' | tac # keep the last.
Run Code Online (Sandbox Code Playgroud)
小智 12
扩展克莱顿答案:
tac $HISTFILE | awk '!x[$0]++' | tac | sponge $HISTFILE
Run Code Online (Sandbox Code Playgroud)
tac
反转文件,确保您已安装moreutils
以便sponge
可用,否则使用临时文件。
这是一篇旧帖子,但对于想要打开多个终端并在窗口之间同步历史记录但不重复的用户来说,这是一个永久的问题。
我在 .bashrc 中的解决方案:
shopt -s histappend
export HISTCONTROL=ignoreboth:erasedups
export PROMPT_COMMAND="history -n; history -w; history -c; history -r"
tac "$HISTFILE" | awk '!x[$0]++' > /tmp/tmpfile &&
tac /tmp/tmpfile > "$HISTFILE"
rm /tmp/tmpfile
Run Code Online (Sandbox Code Playgroud)
history -n
从 $HISTFILE 中读取自上次回车以来可能出现在不同终端中的所有行history -w
将更新的缓冲区写入 $HISTFILEhistory -c
擦除缓冲区,因此不会发生重复history -r
重新读取 $HISTFILE,附加到现在的空白缓冲区tac
反转它,然后反转它,以便它可以与历史记录中最新的命令一起保存每次打开一个新的 shell 时,历史记录都会被擦除,每次您Enter在不同的 shell/终端窗口中按下键时,它都会从文件中更新此历史记录。
这些将保留最后重复的行:
ruby -i -e 'puts readlines.reverse.uniq.reverse' ~/.bash_history
tac ~/.bash_history | awk '!a[$0]++' | tac > t; mv t ~/.bash_history
Run Code Online (Sandbox Code Playgroud)