Как удалить историю последних 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
, но как удалить последние 10 команд и историю между 10 командами, используя одну команду в оболочке?
Можем ли мы написать скрипт bash и выполнить его для удаления истории?
21 ответ
Вы пытались редактировать файл истории напрямую:
~/.bash_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
Это сгенерирует history -d
команды для 1008, затем 1007, затем 1006.
Если я также хотел удалить команду удаления истории, то это немного сложнее, потому что вам нужно знать текущую максимальную запись истории.
Вы можете получить это с (может быть лучший способ):
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
,
С Bash 5 вы теперь можете делать диапазон... Ура!
history -d 511-520
или считая в обратном направлении 10:
history -d -10--1
Отрывок из страницы Bash 5 Man:
"История"
Опции, если они есть, имеют следующие значения:
'-d OFFSET' Удалить запись истории в позиции OFFSET. Если значение OFFSET положительное, его следует указать так, как оно отображается при отображении истории. Если значение OFFSET отрицательное, оно интерпретируется как относительное относительно единицы, превышающей последнюю позицию в истории, поэтому отрицательные индексы отсчитываются с конца истории, а индекс "-1" относится к текущей команде "history -d".
'-d START-END' Удалить записи истории между позициями START и END включительно. Положительные и отрицательные значения для START и END интерпретируются, как описано выше.
Вот мое решение для Bash 4:
delHistory () {
count=$(( ${2:-$1} - $1 ))
while [[ $count -ge 0 ]] ; do
history -d "$start"
((count--))
done
}
delHistory 511 520
Сначала введите: history
и запишите последовательность номеров строк, которые вы хотите удалить.
Чтобы очистить строки, скажем, от 1800 до 1815, напишите в терминале следующее:
$ for line in $(seq 1800 1815) ; do history -d 1800; done
Если вы хотите удалить историю для команды удаления, добавьте +1 для 1815 = 1816 и историю для этой последовательности + команда удаления будет удалена.
Например:
$ for line in $(seq 1800 1816) ; do history -d 1800; done
Совмещаем ответы сверху:
history -w
vi ~/.bash_history
history -r
Я использовал комбинацию решений в этой теме, чтобы стереть след в истории команд. Сначала я проверил, где хранится история команд:
echo $HISTFILE
Я редактировал историю с:
vi <pathToFile>
После этого я очищаю текущий буфер истории сеанса:
history -r && exit
В следующий раз, когда вы войдете в этот сеанс, последняя команда, которую вы увидите в истории команд, является последней, которую вы оставили в pathToFile.
Может быть кому-то пригодится.
Когда вы входите в систему для любого пользователя любой истории консолей / терминалов, ваш текущий сеанс существует только в некотором "буфере", который сбрасывается в ~/.bash_history при выходе из системы.
Так что, чтобы держать вещи в секрете, вы можете просто:history -r && exit
и вы выйдете из системы с очищенной историей всей (и только) сессии;)
редактировать:
Поменял итераторы в скобках, хороший звонок. Также вызовите эту функцию с помощью обратного итератора.
Вы, вероятно, можете сделать что-то вроде этого:
#!/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
Обратите внимание, что я не поместил никаких ошибок проверки границ. Я оставлю это в качестве упражнения для читателя.
см. также этот вопрос
Не напрямую запрошенный ответ, но, возможно, основная причина вопроса:
Вы также можете предотвратить попадание команд в историю, добавив к ним префикс пробела:
# This command will be in the history
echo Hello world
# This will not
echo Hello world
Удалить последние 10 записей (на основе вашего примера):
history -d 511 520
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;
Грубый, но функциональный
Коротко, но мило: for i in {1..10}; do history -d $(($HISTCMD-11)); done
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.
Попробуйте следующее:
for i in {511..520}; do history -d $i; echo "history -d $i"; done
#delete ten times the last history line
for i in $(seq 1 10)
do
n=$(history 1 | awk '{print $1}')
history -d $n
done
Я использую это (у меня есть 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 записей.
Я использую этот скрипт, чтобы удалить последние 10 команд в истории:
pos=$HISTCMD; start=$(( $pos-11 )); end=$(( $pos-1 )); for i in $(eval echo "{${start}..${end}}"); do history -d $start; done
Оно использует $HISTCMD
окружение var, чтобы получить индекс истории и использует его для удаления последних 10 записей в history
,
Простая функция может убить всех по номеру (хотя она и ошибается)
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`
в
history -d
arg принимает диапазон и
$HISTCMD
это максимальное число в истории.
Эта функция работает, чтобы удалить последний
n
записи из истории (просто введите количество команд истории для удаления лайков, например
rmhist 5
):
$ rmhist() { history -d $(($HISTCMD - $1))-$HISTCMD ;}
Или .. Пофантазируйте с таким аргументом, чтобы удалить из точки в истории (включительно) или последних команд '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