zshの履歴をマージする

複数のzshのコマンド履歴ファイルを1つのコマンド履歴ファイルへマージするperlスクリプト。

複数のホストを使っていると、それぞれのホストでzshのヒストリが溜まってきます。これらをマージして1つのファイルにまとめるスクリプトです。ソースは2ch(zsh入門パート2260)です。ここに書いてあったものにuniqする処理を加えただけです。

zshは、ターミナル間のコマンド履歴はファイルを介して自動的に共有できます。それなので、単一のホストを使用している場合はもちろん、ホームディレクトリをNFSでマウントしたような場合であっても、それぞれのホストで打った履歴は共有して記録することができます。そういう場合にはこれを使う必要はありません。このスクリプトは、まったく異なる環境で記録した複数のヒストリファイルをマージすることを想定しています。

このスクリプトは、setopt extended_historyオプションをセットしたzshで記録した履歴ファイル(「日付入り」の履歴ファイル)を期待して動作します。つまり、

:開始時間:所要時間;コマンド

の形式の履歴ファイルです。

USAGE: cat history-file1 history-file2 | histmerge > history-merged
#!/usr/bin/perl -w
use strict;
my @lines;
while (<>)
{
  while (/\\\Z/)
  {
    $_ .= <>;
  }
  push @lines, $_;
}
my %seen=();
print grep { not $seen{$_}++ } @lines;

動作例

$ sdiff .zsh-history.1 .zsh-history.2
: 1324302361:0;ls           : 1324302361:0;ls
: 1324302371:0;ls -la       : 1324302371:0;ls -la
: 1324302378:0;exit         : 1324302378:0;exit
                          > : 1324302690:0;for i in *; do\
                          > echo $i\
                          > done
                          > : 1324302697:0;exit

マージしてみた様子

$ cat .zsh-history.1 .zsh-history.2| ./merge
: 1324302361:0;ls
: 1324302371:0;ls -la
: 1324302378:0;exit
: 1324302690:0;for i in *; do\
echo $i\
done
: 1324302697:0;exit

コメントをどうぞ