シェルで最後の10コマンドの履歴を削除する方法は?


131

コマンドは次のとおりです

  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スクリプトを記述して、履歴の削除を実行できますか?


18
vi $HISTFILE必要なものを削除します。head -n -10自動化する必要がある場合に使用します。
アントンコバレンコ2013

この質問は主題外ですか?またはこれはこの種の質問をするのに適切な場所ではありませんか?もしそうなら、私はこの質問をどこに尋ねるべきですか、私はスタック交換のどこを意味しますか?
ジャスティンジョン

1
シェルコマンドは、ローカルにログインしていても、sshを介してログインしていても同じように機能します。
Barmar 2013

2
UnixとLinuxのStackExchange(unix.stackexchange.com)は、おそらくこの質問に適しています。プログラミングに厳密に関連していないため、ここではトピックから外れています。
ダンモールディング

4
シェルスクリプトのプログラミングは、この質問の理想的な解決策です。そのため、プログラミングに関連していると考える必要があります。OPが実際にスクリプトを具体的に要求したことは言うまでもありません。
SSH

回答:


109

履歴ファイルを直接編集してみましたか?

~/.bash_history

2
@WherethereisaWill OPは手動のプラグアンドチャグではなくスクリプトを必要としていました。
タイラーヤンドロ、2013

10
ターミナルを再起動(閉じて再度開いた)した後に有効になります
khaled_webdev '11 / 12/14

8
vimでこれを行うと、削除履歴が見つかる可能性があるため、削除することも忘れないでください~/.viminfo
ウォルトウッド2015

5
時にはそれは、メモリ内に保持されますし、任意の手動編集は、次のログイン..後に永続化する習慣
スーパーヒーロー

5
@FizerKhanつまり、で行われた変更は.bash_history、メモリに保持されている内容によって上書きされる可能性があります。私はこの解決策が役に立ったと感じました:superuser.com/a/384383/253543
スーパーヒーロー

73

私の回答は以前の回答に基づいていますが、順序を逆にして、履歴アイテムが最新のものから最も古いものへと削除されるようにしています。

現在の履歴を取得します(表示する行数を調整します):

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

これによりhistory -d、1006のコマンドが生成され、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 | tail -1 | awk '{print $1}'簡略化できますhistory 1 | awk '{print $1}'
ジョージヒリアード

-bash: tac: command not foundMac OSXでは、そうでなければこれが最良の答えです。
ジム

for h in $(seq 1006 1008); do history -d 1006; doneこれはubuntu 16.04で動作します
mahfuz

短いが甘い:for i in {1..10}; do history -d $(($HISTCMD-11)); done
錬金術

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

3
最初の引数には必ず大きい数値を使用してください。そうしないと、他のすべてのコマンドが削除されます。たとえば、コマンド511が削除されると、すべてがシフトダウンして、512が新しい511になり、513が新しい512になります。そのためhistory -d 511、期待どおりに機能し、history -d 512かつて513であったものを削除し、512はコマンド511として履歴に残ります。 。
マシュー

5
@マシューそれは必要ありません。$xループを毎回削除するのではなく、を削除し$1ます。したがって、最初に511が削除され、512が511になります。次に、再度511が削除されます。
Barmar

@Matthew私がタイラーの答えに同様のコメントをしたことに注意してください。私はその解決策として自分の解決策を思いつきました。
Barmar

あなたが正しい、私の急いでこれを私が使用した私のbashプロンプトの1行に書き込んだときfor i in...そしてhistory -d $i、上記の私のコメントで説明した結果を得ました。元の回答で述べたように、$ 1を使用することは完全に正しいことです。
マシュー

18

まず、次のように入力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ではまだ正しく機能しません。:(行番号の部分が正しく機能していないようです
Binod Kalathil

Binodが提案した編集は論理的なエラーではないため、私は拒否しました。Ghassanの元のコードは、Barmarの回答と同じアプローチを使用しています。Barmarの回答へのコメントは、1800を置き換えるという提案$line1行おきに削除さ、その後望ましい範囲を超える理由を説明しています。
Anthony Geoghegan

18

Bash 5を使用すると、範囲を実行できるようになります...

history -d 511-520

または逆算10:

history -d -10--1

Bash 5 Man Pageからの抜粋:

'歴史'

オプションが指定されている場合、次の意味があります。

'-d OFFSET'オフセット位置の履歴エントリを削除します。OFFSETが正の場合、履歴が表示されるときに表示されるとおりに指定する必要があります。OFFSETが負の場合、最後の履歴位置よりも1大きいと解釈されるため、負のインデックスは履歴の最後からカウントされ、インデックス「-1」は現在の「history -d」コマンドを参照します。

'-d START-END' STARTとENDの間の履歴エントリを削除します。STARTおよびENDの正および負の値は、上記のように解釈されます。

これがBash 4の私の解決策です。これは、単一のエントリまたは最小のインデックスから始まる履歴の範囲を繰り返し削除します。

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

delHistory 511 520


9

編集:

ブレースイテレータを変更しました。また、この関数を逆反復子で呼び出します。

あなたはおそらくこのようなことをすることができます:

#!/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

境界にエラーチェックを入れていないことに注意してください。読者への課題として残しておきます。

この質問も参照してください


6
510を削除すると、511は510になり、512は511になります。したがって、これにより1行おきに削除されます。
Barmar 2013

ブレース展開に変数を含めることはできません。
chepner 2013

seq 563 514何も印刷されません。あなたが必要seq 563 -1 514です。または、history -d $1引数を次のように使用することもできます514 563
anishsane

9

多分誰かのために役立つでしょう。
現在のセッションのコンソール/ターミナル履歴のユーザーにログインすると、ログアウト時に〜/ .bash_historyにフラッシュされる一部の「バッファー」にのみ存在します。
だから、物事を秘密に保つためにあなたはただ次の
history -r && exit
ことができます:そしてあなたはすべてのセッションの(そして唯一の)履歴がクリアされてログアウトされます;)


5

このスレッドで共有されているソリューションの組み合わせを使用して、コマンド履歴のトレースを消去しました。まず、保存されたコマンドの履歴がどこにあるかを確認しました:

echo $HISTFILE

私は歴史を次のように編集しました:

vi <pathToFile>

その後、現在のセッション履歴バッファーを次のようにフラッシュします。

history -r && exit

次にこのセッションに入るとき、コマンド履歴に表示される最後のコマンドは、pathToFileに残された最後のコマンドです


これは私にとってはうまくいきます。@ jgcからの回答のために、サーバーに再度ログインすると、履歴が再び戻ってきます。ログインしたセッションに対してのみ働きます
Yogeshwar Tanwar


1

最後の10エントリを削除するには(例に基づく):

history -d 511 520

1
GNU bashバージョン4.3.11(1)では、リストの最初の行のみが削除されます
Gary

1

このスクリプトを使用して、履歴の最後の10個のコマンドを削除します。

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

$HISTCMD環境変数を使用して履歴インデックスを取得し、それを使用しての最後の10エントリを削除しますhistory


1

以下を試してください:

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

これは、彼が既に履歴をリストしていて、すべてのIDを事前に知っていることを前提としています
Markoorn

それ以外の場合、「履歴の位置が範囲外です」
devwebcl

それがなければなりません:for i in {511..520}; do history -d $i; echo "history -d 511"; done
devwebcl

1

私はこれを使用します(私は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エントリを削除します。


1
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;

ブルートだが機能的


0
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に変更します。


0

単純な関数は、すべてを数値で殺すことができます(エラーが発生した場合でも)

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`

0

短いが甘い: for i in {1..10}; do history -d $(($HISTCMD-11)); done

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.