.bash_historyから重複を削除して順序を維持する方法は?

.bash_historyから重複を削除して順序を維持する方法は?

control+r私はコマンド履歴を検索するために再帰を使用するのが大好きです。私が使用したいいくつかの良いオプションを見つけました。

# ignore duplicate commands, ignore commands starting with a space
export HISTCONTROL=erasedups:ignorespace

# keep the last 5000 entries
export HISTSIZE=5000

# append to the history instead of overwriting (good for multiple connections)
shopt -s histappend

私にとって唯一の問題は、連続erasedupsした重複エントリのみを削除することでした。したがって、次のコマンド文字列を使用してください。

ls
cd ~
ls

コマンドはls実際には2回記録されます。定期的にcronを実行することを検討しました。

cat .bash_history | sort | uniq > temp.txt
mv temp.txt .bash_history

これにより重複項目が削除されますが、残念ながら順序は維持されません。そのファイルを最初に使用しないと機能sortしないと思いますuniq

.bash_historyから重複を削除して順序を維持する方法は?

追加クレジット:

.bash_historyスクリプトを介してファイルを上書きするのに問題がありますか?たとえば、Apacheログファイルを削除する場合は、nohup / Resetシグナルを送信してkillファイルへの接続をフラッシュする必要があると思います。ファイルの場合の場合、フィルタスクリプトを実行する前に接続されたセッションがないことを確認して確認する.bash_historyために使用できる方法はありますか?ps

答え1

だから、重複した項目に迷惑をかけた後、私は同じことを探してい~/.bash_profileました~/.bashrc

export HISTCONTROL=ignoreboth:erasedups

これはユーザーが望むことをほぼ正確に行い、1つのシェルインスタンスにある最新のコマンドのみを保持します。ignoreboth実際に仕事をしてignorespace:ignoredups仕事erasedupsを終わらせてください。

少なくとも私のMac端末では、bashは完璧に動作します。それを発見askubuntu.comにアクセスしてください。

これはignoredups従来では役に立ちません.bash_history。重複したエントリは、使用中にファイルに表示され続けますshopt -s histappend

答え2

ソート履歴

このコマンドは次のように動作しますsort|uniqが、行を所定の位置に保持します。

nl|sort -k 2|uniq -f 1|sort -n|cut -f 2

デフォルトでは、各行の前に番号を付けます。 -ingの後、sort|uniqすべての行は元の順序(行番号フィールドを使用)に従って並べ替えられ、行番号フィールドは行から削除されます。

この解決策の欠点は、同じラインクラスのどの代表が出力に表示されるか定義されていないため、最終出力でその位置が定義されていないことです。ただし、最新の代表者を選択する必要がある場合は、sort2番目のキーで入力できます。

nl|sort -k2 -k 1,1nr|uniq -f1|sort -n|cut -f2

admin.bash_history

履歴を再度読み書きするには、history -aそれぞれと を使用できます。history -w

答え3

実際の環境でこのソリューションを見つけてテストしました。

awk '!x[$0]++'

行で特定の値($ 0)を初めて表示した場合、x [$ 0]の値は0です。
0 値が反転!して 1 になります。
1と評価されるステートメントは、印刷と呼ばれるデフォルトの動作を引き起こします。

だから、特定のものが初めて$0見えたら印刷されます。

次の(繰り返される)値がx[$0]増加するたびに、
負の値は0になり、0と評価されるステートメントは印刷されません。

最後の重複値を維持するには、履歴を元に戻し、同じ awk を使用します。

awk '!x[$0]++' ~/.bash_history                 # keep the first value repeated.

tac ~/.bash_history | awk '!x[$0]++' | tac     # keep the last.

答え4

古い投稿ですが、重複せずに複数の端末を開き、ウィンドウ間の履歴を同期したい人にとっては永続的な問題です。

.bashrcの私の解決策:

shopt -s histappend
export HISTCONTROL=ignoreboth:erasedups
export PROMPT_COMMAND="history -n; history -w; history -c; history -r"
tac "$HISTFILE" | awk '!x[$0]++' > /tmp/tmpfile  &&
                tac /tmp/tmpfile > "$HISTFILE"
rm /tmp/tmpfile
  • histappendオプションは、バッファーの履歴を履歴ファイル($ HISTFILE)の末尾に追加します。
  • ignoreboth と Erasedups は、重複エントリが $HISTFILE に保存されるのを防ぎます。
  • 履歴キャッシュを更新するプロンプトコマンド
    • history -n$ HISTFILEは、最後のキャリッジリターン以降に他の端末に表示される可能性があるすべての行を読み取ります。
    • history -w更新されたバッファを$ HISTFILEに書き込む
    • history -c重複が発生しないようにバッファをクリアします。
    • history -r$HISTFILE を再度読み込み、空のバッファーに追加
  • awkスクリプトは、遭遇する各行の最初の発生を保存します。tac元に戻し、歴史的に最新のコマンドとして保存できるように戻します。
  • rm /tmp ファイル

新しいシェルを開くたびに履歴が消去され、Enter別のシェル/ターミナルウィンドウでキーを押すたびに、ファイル内のこの履歴が更新されます。

関連情報