如何删除 shell 中最后10个命令的历史记录?

命令如下

  511  clear
512  history
513  history -d 505
514  history
515  history -d 507 510 513
516  history
517  history -d 509
518  history
519  history -d 511
520  history

我可以通过 history -d 511删除单个命令,但是如何在 shell 中使用单个命令删除最后10个命令和10个命令之间的历史记录呢?

我们可以编写 bash 脚本并执行删除历史记录吗?

362433 次浏览

您是否尝试过直接编辑历史文件:

~/.bash_history

编辑:

改变了带括号的迭代器,很好的调用。同时,用反向迭代器调用这个函数。

你可以这样做:

#!/bin/bash
HISTFILE=~/.bash_history   # if you are running it in a
# non interactive shell history would not work else
set -o history
for i in `seq $1 $2`;
do
history -d $i
done
history -w

在那里,你会像这样唤起:

./nameOfYourScript 563 514

注意,我没有为边界检入任何错误,这将留给读者作为练习。

另见 这个问题

for x in `seq $1 $2`
do
history -d $1
done

首先,键入: history并写下要删除的行号序列。

让我们把第1800到1815行写成以下内容:

$ for line in $(seq 1800 1815) ; do history -d 1800; done

如果要删除删除命令的历史记录,请为1815 = 1816添加 + 1,该序列的历史记录 + 删除命令将被删除。

例如:

$ for line in $(seq 1800 1816) ; do history -d 1800; done

我的答案是基于以前的答案,但加上逆序,以便历史项目从最近删除到最近。

获取当前历史记录(调整要查看的行数) :

history | tail -n 10

这让我觉得

1003  25-04-2016 17:54:52 echo "Command 1"
1004  25-04-2016 17:54:54 echo "Command 2"
1005  25-04-2016 17:54:57 echo "Command 3"
1006  25-04-2016 17:54:59 echo "Command 4"
1007  25-04-2016 17:55:01 echo "Command 5"
1008  25-04-2016 17:55:03 echo "Command 6"
1009  25-04-2016 17:55:07 echo "Command 7"
1010  25-04-2016 17:55:09 echo "Command 8"
1011  25-04-2016 17:55:11 echo "Command 9"
1012  25-04-2016 17:55:14 echo "Command 10"

为要删除的项目选择开始和结束位置。我要删除1006到1008条目。

for h in $(seq 1006 1008); do history -d 1006; done

这将为1006生成 history -d命令,然后1007变成1006并删除1006,然后1008(变成1007)现在是1006并被删除。

如果我还想删除历史删除命令,那么它会有点复杂,因为您需要知道当前的最大历史条目。

你可以用(可能有更好的方法) :

history 1 | awk '{print $1}'

将它们组合在一起,您可以使用它来删除一个范围,还可以删除历史删除命令:

for h in $(seq 1006 1008); do history -d 1006; done; history -d $(history 1 | awk '{print $1}')

将这些都包装在一个函数中,然后添加到 ~/.bashrc中:

histdel(){
for h in $(seq $1 $2); do
history -d $1
done
history -d $(history 1 | awk '{print $1}')
}

删除命令4、5和6(1049-1051)并隐藏证据的示例:

[18:21:02 jonathag@gb-slo-svb-0221 ~]$ history 11
1046  25-04-2016 18:20:47 echo "Command 1"
1047  25-04-2016 18:20:48 echo "Command 2"
1048  25-04-2016 18:20:50 echo "Command 3"
1049  25-04-2016 18:20:51 echo "Command 4"
1050  25-04-2016 18:20:53 echo "Command 5"
1051  25-04-2016 18:20:54 echo "Command 6"
1052  25-04-2016 18:20:56 echo "Command 7"
1053  25-04-2016 18:20:57 echo "Command 8"
1054  25-04-2016 18:21:00 echo "Command 9"
1055  25-04-2016 18:21:02 echo "Command 10"
1056  25-04-2016 18:21:07 history 11
[18:21:07 jonathag@gb-slo-svb-0221 ~]$ histdel 1049 1051
[18:21:23 jonathag@gb-slo-svb-0221 ~]$ history 8
1046  25-04-2016 18:20:47 echo "Command 1"
1047  25-04-2016 18:20:48 echo "Command 2"
1048  25-04-2016 18:20:50 echo "Command 3"
1049  25-04-2016 18:20:56 echo "Command 7"
1050  25-04-2016 18:20:57 echo "Command 8"
1051  25-04-2016 18:21:00 echo "Command 9"
1052  25-04-2016 18:21:02 echo "Command 10"
1053  25-04-2016 18:21:07 history 11

问题实际上是从历史中删除最后10条命令,所以如果您想节省一点功夫,您可以使用另一个函数来调用 histdel函数,该函数为您执行计算。

histdeln(){


# Get the current history number
n=$(history 1 | awk '{print $1}')


# Call histdel with the appropriate range
histdel $(( $n - $1 )) $(( $n - 1 ))
}

此函数接受1个参数,即要删除的前一个历史记录项的数量。因此,要从历史中删除最后10条命令,只需使用 histdeln 10

history -c将清除所有历史记录。

for h in $(seq $(history | tail -1 | awk '{print $1-N}')  $(history | tail -1 | awk '{print $1}') | tac); do history -d $h; done; history -d $(history | tail -1 | awk '{print $1}')

如果您想删除10行,那么只需将 N 的值更改为10。

一个简单的函数可以通过数字杀死所有的人(尽管它会吐出错误)

kill_hist() {
for i in $(echo $@ | sed -e 's/ /\n/g;' | sort -rn | sed -e 's/\n/ /;')
do
history -d $i;
done
}
kill_hist `seq 511 520`
# or kill a few ranges
kill_hist `seq 1001 1010` `seq 1200 1201`

综合以上答案:

历史 Vi ~/. bash _ history History-r

也许对某人有用。
当您登录到当前会话的任何控制台/终端历史记录的任何用户时,只存在于某个刷新到 ~/的“缓冲区”中。注销时的 bash _ history。
所以,为了保守秘密,你可以:
history -r && exit
您将在清除了所有会话(也是唯一的)历史记录后退出;)

删除最后10个条目(基于你的示例) :

history -d 511 520

我使用这个脚本删除历史中的最后10条命令:

pos=$HISTCMD; start=$(( $pos-11 )); end=$(( $pos-1 )); for i in $(eval echo "{${start}..${end}}"); do history -d $start; done

它使用 $HISTCMD环境变量获取历史索引,并使用该索引删除 history中的最后10个条目。

我使用这个线程中共享的解决方案的组合来删除命令历史记录中的跟踪。 首先,我用以下命令验证了命令历史记录的保存位置:

echo $HISTFILE

我编辑了历史:

vi <pathToFile>

之后,我将当前会话历史缓冲区刷新为:

history -r && exit

下次进入此会话时,您将在命令历史记录中看到的最后一个命令是您在 PathToFile上留下的最后一个命令。

试试以下方法:

for i in {511..520}; do history -d $i; echo "history -d $i"; done

有了 Bash 5,你现在可以做一个范围... 万岁! :

history -d 511-520

或倒数10:

history -d -10--1

节选自 Bash 5 Man Page:

“历史”

选项,如果提供,具有以下含义:

“-d 偏移量” 删除位置为 offSET 的历史条目。如果 OffSET 为 时出现,则应指定为 历史记录将显示。如果 OffSET 为负,则为 被解释为相对于一个大于上一个历史 因此,负指数会从 “-1”的索引是指当前的“ history” 指挥官。

’-d 开始-结束’ 删除位置 START 和 END 之间的历史条目, START 和 END 的正值和负值是 解释如上所述。

这是我对 Bash 4的解决方案。它迭代地删除从最低索引开始的单个条目或历史记录范围。

delHistory () {
count=$(( ${2:-$1} - $1 ))
while [[ $count -ge 0 ]]; do
history -d "$1"
((count--))
done
}


delHistory 511 520

我使用这个(我有 bash 4) :

histrm() {
local num=${1:- 1}
builtin history -d $(builtin history | sed -rn '$s/^[^[:digit:]]+([[:digit:]]+)[^[:digit:]].*$/\1/p')
(( num-- )) && $FUNCNAME $num
builtin history -w
}

builtin history的部分,以及最后的 -w是因为我在地方的变化,著名的 跨终端共享历史的技巧和这个功能将中断没有这些部分。它们确保调用真正的 bash history内置函数(而不是我自己的包装函数) ,并在删除条目后立即将历史记录写入 HISTFILE。

然而,这将工作,因为它是“正常”的历史配置。

您应该使用要删除的最后一个条目的数目来调用它,例如:

histrm 10

将删除最后10个条目。

简短但甜蜜: for i in {1..10}; do history -d $(($HISTCMD-11)); done

history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;history -d 511;

残忍但有用

不是直接要求的答案,而是问题的根本原因:

您还可以通过在命令前面加上一个空格字符来防止它们甚至从 进入的历史记录:

# This command will be in the history
echo Hello world


# This will not
echo Hello world

history -d参数取一个范围,而 $HISTCMD是历史上的最大值。

这个函数的作用是从历史记录中删除最后的 n条目(只需传递删除类似的历史命令的数量,例如 rmhist 5) :

$ rmhist()  { history -d $(($HISTCMD - $1))-$HISTCMD ;}

或者. . 使用这样的参数从历史(包括)或 last‘ n’命令中删除:

rmhist() {
case $1 in
--from|from) local start=$2; ;;
--last|last) local start=$(($HISTCMD - $2)) ;;
*) echo "Try rmhist --from # or rmhist --last n "; return ;;
esac;
history -d ${start}-${HISTCMD}
}

结果是这样的:

 5778  ls /etc
5779  ls /tmp
5780  ls /dev
5781  ll
5782  cd /tmp
5783  cd
5784  history
(base) ~ $ rmhist --last 3
(base) ~ $ history 5
5778  ls /etc
5779  ls /tmp
5780  ls /dev
5781  ll
5782  history 5
(base) ~ $ rmhist --from 5780
(base) ~ $ history 5
5776  history 10
5777  ls
5778  ls /etc
5779  ls /tmp
5780  history 5
#delete ten times the last history line
for i in $(seq 1 10)
do
n=$(history 1 | awk '{print $1}')
history -d $n
done