"\n"の代わりに "\0"文字で区切られたzsh履歴をエクスポートする

"\n"の代わりに "\0"文字で区切られたzsh履歴をエクスポートする

アイテム\0\n。組み込みパーサーはfc 123改行を維持するエディターを開き、複数行の項目をきれいに処理します。ただし、fc -l 123(エディタを起動せずに標準出力に印刷)、改行文字を対応する文字に変換します\\n。これは、そのリテラルを含む履歴のすべてのコマンドが\n改行文字と区別できないことを意味します(たとえば、printf "\n"awk呼び出しで)。

fczshまたはzshの組み込み機能を使用してhistory変更されていない履歴項目を取得する方法はありますか?履歴ファイルパーサーの作成を避けたいと思います。ちなみに、フィッシュにはhistory -zこのようなユースケースがあります。

(ボーナス:bashの履歴を分析するために同じことをしたいです。zshfcとは異なる動作をするようです。)

答え1

使用history可変合計パラメータ拡張(含むことができます(関連)配列インデックス)特性。

たとえば、元の対応する項目fc -l 123 123はです$history[123]。配列の記録要素の範囲を取得するには、を使用できます${(v)history[(I)<123-456>]}。文字列から履歴要素のnull区切りリストを取得するには、を使用できます${(vpj[\0])history[(I)<123-456>]}。 (しかし、記録要素にはnullバイトを含めることができ、nullバイトを渡すことはできません。セクションを外部コマンドに追加するので、特に役に立ちません)

到着印刷NULで区切られた場合、バックスラッシュ拡張を無効にするために、をprint -N一緒に使用することもできます。したがって、一致するものがなければ、何も印刷されません。-r-C1

print -rNC1 -- ${(v)history[(I)<123-456>]} | fzf --read0

または:

print -rNC1 -- $history | fzf --read0

歴史をすべて持っていきましょう。

答え2

の場合、bash入力したコマンドの2行目以降の行がスペース、数字、および少なくとも2つのスペースで始まらないと仮定すると、次のことができます。

HISTTIMEFORMAT= history | LC_ALL=C gawk -v RS='\n *[0-9]+  ' -v ORS='\0' '
  NR==1 {sub(/^ *[0-9]+  /, "")}
  {print}'

履歴出力を変換するには(タイムスタンプを削除する)、次の手順を実行します。

  123  cmd
  124  echo 'multiline
command'
  125  ...

到着する:

cmd<NUL>echo 'multiline
command'<NUL>...<NUL>

関連情報