如何从 bash 历史记录中删除重复项?

如何从 bash 历史记录中删除重复项?

由于我正在保存不同会话的历史记录,因此这是一个erasedups无法帮助的问题,因为我正在使用以下内容:

PROMPT_COMMAND="$PROMPT_COMMAND;history -a"

有没有简单的方法可以删除历史记录中的重复项?

答案1

可以通过运行以下命令删除 .bash_history 中已有的重复行:

nl ~/.bash_history | sort -k 2  -k 1,1nr| uniq -f 1 | sort -n | cut -f 2 > unduped_history

其次是

cp unduped_history ~/.bash_history

我还建议将以下内容放入您的 ~/.bashrc 中:

export HISTCONTROL=ignoreboth:erasedups

答案2

这里还有更多方法可以执行此操作,以及其他一些正在进行的设置/选项:

https://unix.stackexchange.com/questions/48713/how-can-i-remove-duplicates-in-my-bash-history-preserving-order

sort ~/.bash_history | uniq -u

或者在 vim 文本编辑器中 :sort u

如果包括上述建议在内的某些建议没有立即起作用。运行代码后,我会这样做:

history -c

首先清除历史记录,然后恢复无重复的版本:

mv unduped_history ~/.bash_history

答案3

我为此创建了一个小型 Python 脚本deduplicate.py。如果某一行重复,脚本只会保留最后重复的行。这在使用以下方式搜索命令历史记录时效果很好:fzf使用Ctrl+r因为它首先显示后面的条目:

#!/usr/bin/env python

# Deduplicates the lines of a file.
# Doesn't change the file, just writes the result
# to standard out.

import sys

if len(sys.argv) >= 2:
    unique_lines = []

    file_name = sys.argv[1]

    with open(file_name, 'r') as fi:
        for line in reversed(list(fi)):
            if line not in unique_lines:

                # If a command occurs multiple times in the file, we
                # keep the more recent one (the one closer to the end
                # of .bash_history).
                # This is useful when searching .bash_history with FZF
                # using ctrl+r, since per default, FZF reverses the
                # lines in .bash_history and we see more recent
                # commands first.
                unique_lines.insert(0, line)

    for unique_line in unique_lines:
        print(unique_line, end='')

else:
    print('Please provide an input file path', file=sys.stderr)

我每小时都这样称呼它systemd服务位于~/.config/systemd/user/deduplicate_bash_history.service

[Unit]
Description=Remove duplicate lines from ~/.bash_history.

[Service]
# We use -c to get a login shell for accessing the home directory
ExecStart=/bin/bash -c "~/scripts/deduplicate.py ~/.bash_history > ~/.bash_history_deduplicated && mv --force ~/.bash_history_deduplicated ~/.bash_history"
# We have to create a temporary file, since the following direct method would create a .bash_history containing only the entry of this command:
#/bin/bash -c "~/scripts/deduplicate.py ~/.bash_history > ~/.bash_history"

并且此计时器位于~/.config/systemd/user/deduplicate_bash_history.timer

[Unit]
Description=Remove duplicate lines from ~/.bash_history.

[Timer]
OnCalendar=hourly

[Install]
WantedBy=timers.target

我使用

systemctl --user daemon-reload && systemctl --user enable deduplicate_bash_history.timer

并确保它是使用

systemctl --user list-timers --all

相关内容