ハイパーマッスルエンジニア

Vim、ShellScriptについてよく書く

fzfは非表示にした列でフィルタリングすることはできない

--with-nthで特定の列だけを表示した上でフィルタリングがしたかったが、どうもできないらしい。

github.com

上記のIssueによると、できないというよりはそれを実装してしまうと混乱を招きそうだから実装しない、ということらしい。

何がしたかったのか

fzfの絞り込み結果は日本語で表示し、フィルタリングは英語で行う、ということをしたかった。

例えばこんなファイルがあるとする。

Ken.tsv

神奈川    Kanagawa
東京  Tokyo
横浜  Yokohama

このファイルをfzfに食わせると下記のようになる。

f:id:rasukarusan:20200726232403p:plain

上記のように列が2つだけならこのままフィルタリングしていっても特に問題はない。
ただ列が多くなってきたときに、特定の列だけを表示した上でフィルタイングしたいときがある。
今回の場合だと、表示は神奈川県などの日本語だけにして、フィルタリングはkanagawaなどローマ字でやりたいっていうケースですね。

f:id:rasukarusan:20200726232437p:plain
イメージこんな感じ

そしてこれはできないよっていうのが冒頭のIssueになります。以下ポエム。

--nth,--with-nthについて

--nth,--with-nthは列(field)を扱うオプション。 ざっくり違いをまとめると以下。

  • --nthフィルタリングを適用させたい列を指定することができる
  • --with-nth表示したい列を指定することができる

ちなみにnthというのは4th5thの数字の部分をNとした形のこと。いわゆる序数ってやつですね。

nth系の挙動を下記のようなファイルで試してみる。

Ken.tsv

神奈川(kanagawaken)   Kanagawa
東京(tokyoto) Tokyo
横浜(yokohamashi) Yokohama

--nth=1(1列目でフィルタリング)

まずは--nthの挙動から確かめてみる。

cat Ken.tsv | fzf --nth=1

f:id:rasukarusan:20200726232504p:plain
1列目でフィルタリングされる

1列目の(kanagawaken)でフィルタリングされている。

--nth=2(2列目でフィルタリング)

では--nth=2にした場合どうなるか。

cat Ken.tsv | fzf --nth=2

f:id:rasukarusan:20200726232526p:plain
2列目でフィルタリングされる

2列目のKanagawaでフィルタリングされている。

このように--nthはフィルタリングを適用させる列を指定することができる。

--with-nth=1(1列目だけ表示)

cat Ken.tsv | fzf --with-nth=1

f:id:rasukarusan:20200726232543p:plain
1列目だけ表示される

1列目だけ表示されている。もちろん--with-nth=2とすると2列目だけ表示される。

--with-nth=N..(N列目以降表示)

2..のように..を使用することでN列目以降を表現できる。

Ken.tsv

神奈川    Kanagawa    1234km
東京  Tokyo   5678km
横浜  Yokohama    10km
cat Ken.tsv | fzf --with-nth=2..

f:id:rasukarusan:20200726232624p:plain
2列目以降が表示される

--nth,--with-nthを組み合わせれば非表示の列でフィルタリングできるんじゃない!?

下記のように--nth--with-nthを組み合わせればいけると思った。

# フィルタリング対象を2列目、1列目だけを表示する
cat Ken.tsv | fzf --nth=2 --with-nth=1

と思ったけどできなかった。これについては下記。

github.com

終わり

fzfを使い始めてからずっと疑問だったことが解消されたし、--nthについてもちゃんと理解することができたので結果オーライ。
どうしてもやりたかったらForkして修正したものを使えばいいという選択肢があるだけで神。
ああfzf楽しい。