命令如下
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脚本并执行以删除历史记录吗?
vi $HISTFILE并删除所需的内容。 如果必须自动使用head -n -10。
为什么使用ssh标签?
这个问题是题外话吗? 还是这不是问这类问题的好地方? 如果是这样,我应该在哪里问这个问题,我的意思是堆栈交换在哪里?
@Barmar:我正在使用ssh。
无论您是本地登录还是通过ssh登录,Shell命令的工作方式都相同。
Unix和Linux StackExchange(unix.stackexchange.com)可能是解决此问题的更好场所。 它不在主题之列,因为它与编程没有严格关系。
@DanMoulding这个问题可以迁移到unix.stackexchange.com吗? 如果是这样,怎么办?
对shell脚本进行编程是解决此问题的理想方法,因此应考虑与编程相关。 更不用说OP实际上确实要求脚本。
您是否尝试过直接编辑历史文件:
~/.bash_history
@WherethereisaWill OP需要脚本,而不是手动的即插即用。
将在重新启动(关闭并重新打开)终端后生效
如果使用vim执行此操作,则可能会在~.viminfo中找到删除历史记录,因此请确保也将其删除!
有时它会保留在内存中,并且任何手动编辑在下次登录后都不会保留。
@ErikLandvall您必须关闭终端并打开另一个终端并编辑历史文件。
@FizerKhan不会帮助它保留在内存中。它的历史文件有时会保留在内存中,因此即使您编辑该文件也不会生效。
@ErikLandvall理解。您的意思是:即使我关闭终端,也不能保证将历史记录写入.bash_history文件吗?
@FizerKhan我的意思是.bash_history中所做的更改可以被内存中的内容覆盖。我发现此解决方案很有帮助:superuser.com/a/384383/253543
及其zsh的?/ .zsh_history。不要忘记重新启动终端
我的答案基于先前的答案,但是增加了反向顺序,以便将历史项从最近删除到最近。
获取当前的历史记录(调整您要查看的行数):
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 | tac); do history -d $h; done
这将为1008然后1007然后1006生成history -d命令。
如果我还想删除history delete命令,则它要复杂一些,因为您需要了解当前的最大历史记录条目。
您可以使用以下方法(可能有更好的方法):
history 1 | awk '{print $1}'
放在一起,您可以使用它删除范围,也可以删除历史删除命令:
for h in $(seq 1006 1008 | tac); do history -d $h; done; history -d $(history 1 | awk '{print $1}')
将所有内容包装在一个函数中,以添加到您的~/.bashrc中:
histdel(){
for h in $(seq $1 $2 | tac); do
history -d $h
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 | tail -1 | awk {print $1}可以简化为history 1 | awk {print $1}
for x in `seq $1 $2`
do
history -d $1
done
请确保对第一个参数使用更高的数字,否则您将删除所有其他命令。例如。当删除命令511时,所有内容向下移动,因此512成为新的511,而513成为新的512。因此history -d 511可以按预期工作,然后history -d 512删除以前的513,并且512作为命令511保留在历史记录中希望有道理。
@Matthew Thats不必要。我不会在循环中每次删除$x,而是删除$1。因此,它首先删除511,然后512变为511。然后再次删除511,依此类推。
@Matthew请注意,我对Tylers的回答也有类似的评论。我想出了解决方案来解决此问题。
您是正确的,我匆匆忙忙地在bash提示符下将其写在一行中,使用了for i in ...和history -d $i并获得了我在上面的评论中描述的结果。使用$ 1,这绝对是正确的,如您的原始答案中所述。
结合以上答案:
history -w
vi ~/.bash_history
history -r
首先,键入: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
我进行了更新,但在Ubuntu 12.04中仍然无法正常工作。::(看来行号部分无法正常工作
我拒绝Binods建议的编辑,因为它不是逻辑错误。 Ghassans的原始代码使用与Barmars答案相同的方法-可行。对Barmars答案的注释解释了为什么用$line替换1800的建议会删除其他所有行,然后超出期望的范围。
编辑:
更改了括号迭代器,不错的调用。另外,请使用反向迭代器调用此函数。
您可能可以执行以下操作:
#!/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
注意,我没有对边界进行任何错误检查。我将其留给读者练习。
另见这个问题
删除510后,511变为510,512变为511,依此类推。因此,这将删除每隔一行。
括号扩展中不能包含变量。
seq 563 514将不打印任何内容。您需要seq 563 -1 514。或者,您可以简单地将history -d $1与作为514 563的参数一起使用
也许对某人有用。
当您登录到当前会话的任何控制台/终端历史记录的任何用户时,仅存在于某些"缓冲区"中,该"缓冲区"在您注销时刷新为?/ .bash_history。
因此,要保密,您可以:
history -r && exit
并且您将登出,并且清除了所有会话的(唯一的)历史记录;)
使用Bash 5,您现在可以进行一系列操作了……万岁!
history -d 511-520
或倒数10:
history -d -10--1
Bash 5手册页摘录:
'history'
Options, if supplied, have the following meanings:
'-d OFFSET'
Delete the history entry at position OFFSET. If OFFSET is
positive, it should be specified as it appears when the
history is displayed. If OFFSET is negative, it is
interpreted as relative to one greater than the last history
position, so negative indices count back from the end of the
history, and an index of '-1' refers to the current 'history
-d' command.
'-d START-END'
Delete the history entries between positions START and END,
inclusive. Positive and negative values for START and END are
interpreted as described above.
这是我对Bash 4的解决方案:
delHistory () {
count=$(( ${2:-$1} - $1 ))
while [[ $count -ge 0 ]] ; do
history -d"$start"
((count--))
done
}
delHistory 511 520
那就是我在SO上搜索此问题的方法
我使用了此线程中共享的解决方案的组合来擦除命令历史记录中的跟踪。
首先,我使用以下命令验证了保存命令历史记录的位置:
echo $HISTFILE
我用以下方式编辑了历史记录:
vi
之后,我使用以下命令刷新当前会话历史记录缓冲区:
history -r && exit
下次进入此会话时,在命令历史记录中将看到的最后一个命令是在pathToFile上保留的最后一个命令。
历史记录-c将清除所有历史记录。
请尝试以下操作:
for i in {511..520}; do history -d $i; echo"history -d $i"; done
假设他已经列出了历史记录并且事先知道所有ID
并且它不能是历史记录列表中的最新记录,否则:"历史记录位置超出范围"
它必须是:for i in {511..520}; do history -d $i; echo"history -d 511"; done
我使用此脚本删除历史记录中的最后10条命令:
pos=$HISTCMD; start=$(( $pos-11 )); end=$(( $pos-1 )); for i in $(eval echo"{${start}..${end}}"); do history -d $start; done
它使用$HISTCMD环境var获取历史索引,并使用该索引删除history中的最后10个条目。
一个简单的函数可以杀死所有的人(尽管它会因错误而拒绝)
kill_hist() {
for i in $(echo $@ | sed -e 's/ /
/g;' | sort -rn | sed -e 's/
/ /;')
do
history -d $i;
done
}
kill_hist `seq 511 520`
# or kill a few ranges
kill_hist `seq 1001 1010` `seq 1200 1201`
我用这个(我有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 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。
删除最后10个条目(根据您的示例):
history -d 511 520
在GNU bash版本4.3.11(1)中,这仅删除列表中的第一行