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