Как удалить историю последних 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
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

Если вы хотите удалить историю для команды удаления, добавьте +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;

Грубый, но функциональный

История -c очистит все истории.

Коротко, но мило: 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 -darg принимает диапазон и $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
Другие вопросы по тегам