複数のタイムスタンプを持つ.bash_historyファイルをマージする

複数のタイムスタンプを持つ.bash_historyファイルをマージする

.bash_history仮想マシンのスナップショットを切り替えて複数のファイルを作成します。これらすべてのファイルを.bash_history現在実行中のインスタンスの単一のライブファイルに復元したいと思います。

このファイルにはタイムスタンプがあるので、できるだけ保存したいと思います。しかし、一部の行にはタイムスタンプがないようです。たとえば、

#1542817796
vi ~/.bash_profile 
set +x
cd -
cd w/Edge-Agent/edge-agent-ged/
make 
set -x
man make
make -npq
make -npq .DEFAULT
make 
make 
ack npq /etc
ack npq /usr/share/
set +x
ack npq /usr/share/
sudo vi /usr/share/bash-completion/completions/make
dv
hg diff 
vi ~/.bashrc
#1542826064
ls
#1542826066
vi ~/.bashrc
#1542826074
cd ..
#1542826321

スナップショットとファイルの間を行ったり来たりするので、マージされたリストをタイムスタンプで並べ替えたいと思います。コマンドに使用できるタイムスタンプがない場合は、前の最後のタイムスタンプと後の最初のタイムスタンプに基づいてこれを推論できます。

答え1

GNU m4の使用(サポート最大LONG_MAXまで番号を転送)とsed入力の準備に必要ないくつかの追加項目:

#!/bin/sh

{ cat <<"EOF"
m4_define(m4_chunk,`m4_divert(-1)m4_undivert($1)m4_divert($1)#$1')m4_dnl
m4_define(m4_,``m4_'')m4_dnl
m4_define(`m4_LQ',`m4_changequote([,])`m4_dnl'
m4_changequote`'')m4_dnl
m4_define(`m4_RQ',`m4_changequote([,])m4_dnl`
'm4_changequote`'')m4_dnl
EOF
sed -e "s/m4_/m4_()/g;s/\`/m4_LQ()/g;s/'/m4_RQ()/g;s/m4_/\`'m4_/g" -e 's/^#\([0-9]\+\)$/m4_chunk(\1)/'
} | m4 -P

使用法:

cat edgeos_history.* | sort_history.sh > merged_history

このm4_chunk関数は、すべての入力が終了すると個々のブロックが数値の昇順で「変更されない」ため、ほとんどの操作を実行します。スクリプトの残りの部分は、m4_入力の引用と既存のシーケンスが解釈されないように保護することですm4

LQRQMichael Breenの定義に基づいてM4マクロ言語の説明

答え2

同様の操作を行い、cat /path/to/one/.bash_history >> /path/to/live/.bash_history重複した入力を削除してからawk '!seen[$0]++' .bash_history >> .bash_history2元の入力を削除し、.bash_history2の名前を.bash_historyに変更できます。ただし、このように重複エントリを削除すると、空のタイムスタンプが残ります。

答え3

これは役に立ちますか?

awk '/^#[0-9]*$/ {TS = $0; next} {print TS, $0}' file* | sort
#1542817796 ack npq /etc
#1542817796 ack npq /usr/share/
#1542817796 ack npq /usr/share/
#1542817796 cd -
#1542817796 cd w/Edge-Agent/edge-agent-ged/
#1542817796 dv
#1542817796 hg diff 
#1542817796 make 
#1542817796 make 
#1542817796 make 
#1542817796 make -npq
.
.
.

すべての履歴ファイルをawk

編集する:あまり満足のいく移植性のない一部の記事は、命令の元の順序を維持します。

awk '/^#[0-9]*$/ {TS = $0; next} {print TS, NR, $0}' file* | sort  -k1,1 -k2,2n

awk '/^#[0-9]*$/ {TS = $0; next} {print TS,  $0}' file* | sort  -mk1,1 

答え4

私は長い間bashレコード(タイムスタンプを含む)をマージする方法を探していましたが、何も許可されていないようです。

つまり、ディスクの「.bash_history」をメモリのシェル「history」とマージします。タイムスタンプの順序とそのタイムスタンプ内のコマンドの順序は保持されます。

定義されたPerl REに従って、一意のコマンド(複数行を含む)を削除するか、単純で敏感なコマンドを削除(消去)するオプションがあります。合わせて調整してください!

結果は次のとおりです。 https://antofthy.gitlab.io/software/history_merge.bash.txt

スクリプトの最初の「perl」コマンドは、単に入力履歴ファイルをリンクします。デフォルトは、"$HISTFILE" <(history -w /dev/stdout)ディスク内の記録をメモリ内の記録とマージしてタイムスタンプ付きのレコードに分割することです。次に、2番目の「perl」がマージを実行します。

必要に応じて、ディスクの記録またはメモリの記録を置き換えることができる一時ファイルに結果を保存します(現在の両方)。

適切に調整してください。

楽しむ

関連情報