1 - はじめに

greple

greple は、作者が1990年初頭から開発を続けているコマンドです。名前の通り Unix コマンドの grep と同じように、テキストから文字列を検索するためのものです。le は lexical expression の意味ですが、それについてはこれからおいおい説明していきます。

読み方

読み方は特に決めていませんが、なんとなく「ぐれっぷる」と呼んでいます。アクセントは「れ」にあったり、今時の平板化した読み方だったりと、人によって様々です。英語的に発音すると「ぐれぽー」みたいになるんでしょうか。

「ぐれっぷ・えるいー」と読んでもいいけど、長いですね。アメリカ人、なんでも単語化しようとしますしね。SCSI が「すかじー」になるくらいで。昔、PCMCIA を無理やり読んでいる人がいて驚いたことがあります。

特徴

greple は、以下のような特徴を持っています。

  • 複数のキーワードを指定することができる
  • 行だけではなく、検索対象ブロックを柔軟に指定することができる
  • 検索対象の範囲や条件を指定することができる
  • 複数行に渡るパターンを検索することができる
  • 多彩な色指定が可能
  • 設定ファイルやモジュールによるカスタマイズ/拡張が可能
  • 検索だけではなく、文字列処理のフレームワークとして機能する

これらの特徴や使い方について、これから毎日少しずつ解説していこうと思います。

想定される用途

元々、文章の校正作業を楽にするために作ったもので、その後もまとまった翻訳の仕事が入る度に少しずつ拡張を続けてきました。そのため、それほど多くないテキストファイル(せいぜい書籍数冊分程度)に対して、様々な条件を科して検索やそれに類する処理を行うというのが想定される主な使い方です。

大量のデータを対象にするのであれば、それに適したツールが他にたくさんあるので、そういうものを使ってください。ちなみに、ripgrep というコマンドが高速かつ高機能です。

また、greple は、すべてのデータを読み込んでから処理するため、連続して生成されるデータを逐次処理していくような目的に使うことはできません。

インストール

greple は Perl で記述されていて、cpanminus (cpanm) を使ってインストールします。cpanminus の使い方や、Perl の環境設定については、他の記事を参照してください。cpan や cpanplus など、他のインストーラーでも正しく使えば問題ないはずですが、保証はできません。

$ cpanm App::Greple
or
$ curl -sL http://cpanmin.us | perl - App::Greple

リポジトリ

ソースコードは github で管理しています。cpan にも、ほぼ最新版が上がっているので、どちらからインストールしても同じです。cpanm コマンドで、github の URL を指定してインストールすることもできます。

関連記事

2 - 単純な検索

greple の最も単純な使い方は grep と同じです。

greple pattern file

ファイルが指定されなければ、標準入力を対象にします。

grep と共通のオプションもあります。以下に挙げたものは、grep とほぼ同様の意味を持ちますが、挙動が若干違うものもあります。

  • -n 行番号を表示する
  • -i: 大文字小文字を無視する
  • -A, -B, -C: 前後の行を表示する
  • -o: マッチした部分だけを表示する
  • -h, -H: ファイル名の表示を制御する
  • -l: マッチしたファイル名のみを表示する
  • -c: マッチした数を表示する
  • -m: 表示数を制御する

正規表現

greple は、特別なオプションを指定しなくても、パターンに Perl の正規表現をそのまま使うことができます。どのバージョンの正規表現が使えるかは、実行する処理系に依存します。

正規表現は、行単位ではなくファイル全体を対象としてマッチしますが、デフォルトで複数行マッチが有効になっていて、行頭・行末を示す ^$ はすべての行にマッチします。

Perl 発祥の正規表現は PCRE (Perl Compatible Regular Expression) として、様々な言語やツールに組み込まれています。ripgrep の場合は、–pcre2 オプションをつけることで利用可能です。

実行例

次のようなファイルを用意してみました。某寿司チェーンのメニューを参考に少しアレンジしましたが、この程度ならまさか盗用とは言われないでしょう。このファイルに対して greple コマンドを実行してみます。

サービスセット      熟成まぐろ えび たまご いか サーモン いなり ねぎまぐろ サラダ
お子様セット        熟成まぐろ えび たまご いなり ツナサラダ
特上セット          中とろ 熟成まぐろ 熟成真鯛 はまち 赤えび ほたて うなぎ かに いくら
特上極旨セット      中とろ はまち かに いくら 赤えび サーモン うなぎ うに
うどんセット        熟成まぐろ サーモン たまご えび うどん
サラダ軍艦セット    えびマヨ ツナサラダ サラダ シーフードサラダ
人気セット          熟成まぐろ 漬けまぐろ サーモン びんちょう いか えび えびアボカド たまご
まぐろづくしセット  中とろ 熟成まぐろ ねぎまぐろ
プレミアムセット    中とろ まぐろ サーモン 赤えび はまち うなぎ かに いくら

cat -n するとこうです。

スクリーンショット 2021-12-02 17.56.02.png

greple

行番号を表示する -n オプションをつけて greple を実行してみます。

スクリーンショット 2021-12-02 17.59.02.png

greple は、このように、デフォルトで検索した文字列を色付きでハイライトして表示します。最近の検索系コマンドは大概カラー出力に対応しているので珍しくはありません。

grep

grep は、–color オプションをつけることでカラー出力ができます。

スクリーンショット 2021-12-02 18.02.03.png

ripgrep

ripgrep は、デフォルトでハイライト出力します。行番号やファイル名には異なる色がつきます。

image.png

端末以外の出力

これらのコマンドは、出力が端末でない場合には、色付き出力の機能を無効にします。パイプにも着色して出力するためには --color=always オプションを指定します。--color オプションの仕様は、どのコマンドもほぼ共通で、値として never, auto, always を取ります。ただ、grep はデフォルトが never、greple と ripgrep は auto という違いがあります。

まとめ

単純な文字列を指定した検索について説明しました。もっとも、このような使い方であれば greple を使う必要はまったくないので別のツールを使った方がいいでしょう。実行速度に関しては、インタプリタ型の greple はかなり不利ですが、一般的な使い方であれば実用上問題になるようなことはありません。

SEE ALSO

3 - 複数キーワードによる検索

パターンオプション

greple には、パターンを指定するために以下のようなオプションがあります。オプション指定がない場合には、最初のコマンド引数がパターンとされ、これは -le オプションで指定されたのと同様に扱われます。

     PATTERN
       pattern              'and +must -not ?alternative &function'
       -x, --le   pattern   lexical expression (same as bare pattern)
       -e, --and  pattern   pattern match across line boundary
       -r, --must pattern   pattern cannot be compromised
       -v, --not  pattern   pattern not to be matched
           --or   pattern   alternative pattern group
           --re   pattern   regular expression
           --fe   pattern   fixed expression

--le オプションによる複数キーワード指定

--le は lexical expression の略としていて greple の le もここから来ています。単なる文字列ではなくて、意味を持ったトークンの集まりというような意味合いですが、英語として通じるか実はちょっと不安です。とりあえず、ブラウザの検索欄と同じように考えてもらえばいいと思います。

検索エンジンの検索欄に空白で区切って複数の単語を並べると、そのすべての文字列にマッチするページを表示しようとしてくれます。greple の --le オプションも同様で、空白で区切られた検索トークンのすべてが含まれる行を表示します。

前回の寿司セットを例にとってみます。

サービスセット      熟成まぐろ えび たまご いか サーモン いなり ねぎまぐろ サラダ
お子様セット        熟成まぐろ えび たまご いなり ツナサラダ
特上セット          中とろ 熟成まぐろ 熟成真鯛 はまち 赤えび ほたて うなぎ かに いくら
特上極旨セット      中とろ はまち かに いくら 赤えび サーモン うなぎ うに
うどんセット        熟成まぐろ サーモン たまご えび うどん
サラダ軍艦セット    えびマヨ ツナサラダ サラダ シーフードサラダ
人気セット          熟成まぐろ 漬けまぐろ サーモン びんちょう いか えび えびアボカド たまご
まぐろづくしセット  中とろ 熟成まぐろ ねぎまぐろ
プレミアムセット    中とろ まぐろ サーモン 赤えび はまち うなぎ かに いくら

前回はまぐろが入っているセットを検索しましたが、やっぱりはまちも食べたいので、まぐろはまちが入っているセットを探します。

image.png

2つのセットがあることがわかります。

ほたても食べたいと探すと、特上セット一択になりました。

image.png

このように、greple のパターンに空白で区切って複数のキーワードを指定すると、その全てを含む行を表示します。

grep の場合

grep も -e オプションを繰り返し使用することで、複数のキーワードを指定することができます。同じように、まぐろはまちを探してみます。

image.png

grep の場合は、複数のパターンを指定すると、そのいずれかが含まれる行を表示します。

では、まぐろはまちの両方が入っているセットを検索するためにはどうするかというと、まず思いつくのはパイプでつなぐことです。

image.png

あるいは、まぐろはまちの両方が含まれるパターンを指定する方法もあります。

image.png

しかし、これでははまちの方が先に出てきた場合に対応することができません。どちらにも対応しようとするとこうなります。

image.png

この例では grep ではなく egrep を使っています。grep で同じ結果を得るためには |\| に置き換えます。

見てわかるように、まぐろはまち以外の部分もマッチしてしまうので、その部分に色をつけるためには、最後にもう一度 egrep を通します。

image.png

これで grep でも、greple と同じ出力を得ることができました。ただ、これ以上キーワードが増えていくとちょっと大変なので、やはりパイプを使った方がよさそうです。

両方を含む行にマッチする正規表現

順序に関係なくまぐろはまちの両方を含む行にマッチさせる正規表現を作ることも可能です。

image.png

正規表現の先読み (look-ahead) の機能を使って、(?=.*まぐろ)(?=.*はまち) の両方の条件を満たす行頭 (^) を探しています。ripgrep 標準の正規表現は先読みをサポートしていないので --pcre2 オプションを使っています。

幅のない行頭にしかマッチしていないので、まぐろはまちはカラー出力されません。この ^ はなくても同じ結果になりますが、正規表現エンジンの作りによっては非効率な動作になる可能性があるので、あった方がいいでしょう。

マルチカラーハイライト

3種類の寿司ネタを探した例で、それぞれのネタが違う色で表示されていたことに気が付いたでしょうか。

image.png

greple はこのように複数のキーワードが指定された場合、それぞれにマッチする部分を異なる色でハイライトして表示します。色に関するオプションについては、いずれ詳しく説明します。

まとめ

greple で複数のキーワードを指定して、そのすべてが含まれる行を出力する方法について説明しました。

まとまった文章の執筆や校正をしていると、場所は覚えていないけど、どこかにあったはずの説明を参照したくなることがあります。「TCP の再送とタイムアウトについて、どこに書いてあったっけ」というような状況です。この例であれば ‘TCP 再送 タイムアウト’ という3つのキーワードを含む部分を探せばいいわけです。

1行の中にすべてのキーワードが含まれているとは限らないじゃないか、と思われるでしょうか。その通りです。そのような場合についても、いずれ考えてみましょう。

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3

4 - 複数キーワード検索 OR

前回は、指定した複数のキーワードをすべて含む行を表示する方法について説明しました。今回は、A か B のどちらかが含まれればいいという条件を指定する方法について紹介します。

--le オプションの ? 指定

前回と同じ寿司セットの検索を考えます。

サービスセット      熟成まぐろ えび たまご いか サーモン いなり ねぎまぐろ サラダ
お子様セット        熟成まぐろ えび たまご いなり ツナサラダ
特上セット          中とろ 熟成まぐろ 熟成真鯛 はまち 赤えび ほたて うなぎ かに いくら
特上極旨セット      中とろ はまち かに いくら 赤えび サーモン うなぎ うに
うどんセット        熟成まぐろ サーモン たまご えび うどん
サラダ軍艦セット    えびマヨ ツナサラダ サラダ シーフードサラダ
人気セット          熟成まぐろ 漬けまぐろ サーモン びんちょう いか えび えびアボカド たまご
まぐろづくしセット  中とろ 熟成まぐろ ねぎまぐろ
プレミアムセット    中とろ まぐろ サーモン 赤えび はまち うなぎ かに いくら

前回はまぐろはまちの両方を含むセットを探しましたが、はまちが入っているセットは少ないので選択肢が限られます。妥協して、代わりにえびでもいいことにしましょう。

このような場合は、次のようにキーワードの先頭に ? マークを指定します。

greple -n 'まぐろ ?はまち ?えび' sushi.txt

image.png

だいぶ選択肢が増えました。

複数の --le オプションを使う

選択肢が増えて気が大きくなってきたので、上の条件に加えて、うにいくらも食べたくなりました。

greple -n 'まぐろ ?はまち ?えび ?うに ?いくら' sushi.txt

image.png

こうすると、はまち、えび、うに、いくら、のどれかが入っていればいいということになってしまって、期待した結果が得られません。

このような場合は --le を複数回指定します。

greple -n --le 'まぐろ ?はまち ?えび' --le '?うに ?いくら' sushi.txt

image.png

OR キーワードは、それぞれの --le オプション内でグループ化され、オプション同士は AND で評価されるため、全体としては次のような意味になります。

まぐろ AND (はまち OR えび) AND (うに OR いくら)

結果は、それぞれの検索条件毎に色分けされて、見やすく表示されています。

上の例で、最初の --le を省略することはできません。greple は、パターンオプションが指定されていない時のみ、最初の引数をパターンと解釈するので、この --le を省略すると次の引数はファイル名として扱われてしまいます。

正規表現を使う

上の例は、正規表現の | 記法を使って次のように書いても、まったく同じ意味になります。実は ? 記号がついたキーワードについては、内部的にこのような表現に変換して評価しています。

greple -n --le 'まぐろ はまち|えび' --le 'うに|いくら' sushi.txt

image.png

さらには、この例では ? を使っていないので --le オプションは1つにまとめてしまっても問題ないし、その場合は省略することもできます。

greple -n 'まぐろ はまち|えび うに|いくら' sushi.txt

image.png

慣れている人には、この方がわかりやすいかもしれません。

まとめ

--le オプションに複数キーワードを指定する際に、OR 条件を指定する方法を紹介しました。

grep を使って同じことをやろうとすれば、やはりパイプを使うことになると思います。

grep -n まぐろ sushi.txt | egrep 'はまち|えび' | egrep 'うに|いくら

image.png

このくらいになってくると、少し greple を使うメリットが感じられてくるでしょうか。条件が複雑になってくると、条件毎に色分けしてくれるのがありがたく感じられる局面も増えてきます。

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
  3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1

5 - 複数キーワード検索 NOT

これまでに、複数キーワードを使った AND と OR の組み合わせを紹介しました。AND、OR とくれば、当然次は NOT です。

実行例

また寿司セットを使って考えてみます。

サービスセット      熟成まぐろ えび たまご いか サーモン いなり ねぎまぐろ サラダ
お子様セット        熟成まぐろ えび たまご いなり ツナサラダ
特上セット          中とろ 熟成まぐろ 熟成真鯛 はまち 赤えび ほたて うなぎ かに いくら
特上極旨セット      中とろ はまち かに いくら 赤えび サーモン うなぎ うに
うどんセット        熟成まぐろ サーモン たまご えび うどん
サラダ軍艦セット    えびマヨ ツナサラダ サラダ シーフードサラダ
人気セット          熟成まぐろ 漬けまぐろ サーモン びんちょう いか えび えびアボカド たまご
まぐろづくしセット  中とろ 熟成まぐろ ねぎまぐろ
プレミアムセット    中とろ まぐろ サーモン 赤えび はまち うなぎ かに いくら

まぐろは必ず食べたくて、はまちえびのどちらかが入ったセットは、次のようにして探すことができました。

greple -n 'まぐろ はまち|えび' sushi.txt

image.png

でも、実はいくらはアレルギーで食べられないことを思い出しました。

greple -n 'まぐろ はまち|えび いくら' sushi.txt

とすれば、候補の中からいくらを含む食べられないセットを表示することができます。

image.png

でも、本当に探したいのはいくらを含まないセットです。そのような場合には、やはり検索エンジンと同じように、キーワードの先頭にマイナス記号 - を付けます。

greple -n 'まぐろ はまち|えび -いくら' sushi.txt

image.png

これで、望みの結果を得ることができました。

grep -v との違い

grep の -v オプションは、全体から指定したパターンを含まない行を選び出すためのものです。それに対して、greple の NOT キーワードは、他のキーワードによって選ばれた選択肢から、指定したパターンを含むものを削除するためのものです。ですから NOT キーワードだけのパターンはエラーになります。

grep と同様に動作して欲しければ、どの行にも必ずマッチするパターン、たとえば行頭にマッチする ^ を指定することで実現は可能です。ただ、そのために greple を使う必要性は、あまり感じられません。

image.png

まとめ

今回は、複数キーワードを使った検索について AND と OR に続いて NOT の使い方を紹介しました。使い方は簡単で、検索エンジンと同じように、除外したいパターンの先頭に - を付けるだけです。

寿司セットの例は、数が少ないので目grepでも望む情報は得られますが、もし数千行の情報から選び出すとすれば、ツールの力を借りた方が得策です。AND、OR、NOT を組み合わせて情報を絞り込んでいくことで、望みの結果に近づくことができます。

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
  3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
  4. https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703

6 - 複数キーワード検索 MUST

これまでに、複数キーワードを使った検索について AND、OR、NOT と紹介してきました。

今回は、ちょっと変わった MUST について紹介します。

注目したいキーワード

前回は、以下のような寿司セットの中から、まぐろはまちえびを含んでいて、いくらが入っていないものを探すという例を考えました。

サービスセット      熟成まぐろ えび たまご いか サーモン いなり ねぎまぐろ サラダ
お子様セット        熟成まぐろ えび たまご いなり ツナサラダ
特上セット          中とろ 熟成まぐろ 熟成真鯛 はまち 赤えび ほたて うなぎ かに いくら
特上極旨セット      中とろ はまち かに いくら 赤えび サーモン うなぎ うに
うどんセット        熟成まぐろ サーモン たまご えび うどん
サラダ軍艦セット    えびマヨ ツナサラダ サラダ シーフードサラダ
人気セット          熟成まぐろ 漬けまぐろ サーモン びんちょう いか えび えびアボカド たまご
まぐろづくしセット  中とろ 熟成まぐろ ねぎまぐろ
プレミアムセット    中とろ まぐろ サーモン 赤えび はまち うなぎ かに いくら

そして、条件を満たすものは、次のようにして得られました。

greple -n 'まぐろ はまち|えび -いくら' sushi.txt

image.png

しかし、どのセットにいくらが入っていたかにも興味がないでしょうか。いくら以外はいい内容だったら、誰かと交換してもいいかもしれません。もちろん -いくら の指定を外せばいいのですが、そうするとどこにいくらがあるのかを自分の目で探さなければなりません。

このように「なければならない」「あってはいけない」だけではなく、「注目したい」ワードを指定したいことがあります。このような時に使えるのが MUST キーワードです。

+ による MUST 指定

これもまた検索エンジンと同様に、キーワードの先頭にプラス記号 + を付けることで実現します。実際、検索エンジンに複数のキーワードを与えた時に、すべてのキーワードが含まれてはいない結果が表示されることがあります。その時に、絶対にあってほしいキーワードに対して + をつけて検索します。

先の例であれば、このように使います。

greple -n '+まぐろ +はまち|えび いくら' sushi.txt

MUST キーワードがあると、記号なしのキーワードはオプショナルに格下げされます。つまり、いくらはあってもなくても構わないが、あれば色付きで表示されます。

image.png

これも、ハイライトカラーが複数あることの効果が感じられる例です。試しに、単色での表示にしてみると、こんな風になります。

image.png

まとめ

今回は MUST キーワードについて説明しましたが、それによって新たに導入されるのは「オプショナルキーワード」であると言うこともできます。

最後に、以前の記事で紹介した実際の使用例を載せておきます。これは compromise という単語がどういう日本語に翻訳されているかを調べた時のものです。compromise のみを必須として、候補となる訳語を着色して表示しています。いずれ、詳しく説明できるかもしれません。

image.png

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
  3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
  4. https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703
  5. https://qiita.com/kaz-utashiro/items/24ac0b8fdd30b598e069

7 - 複数キーワード検索 単独オプション

これまで --le オプションを使って、複数のキーワードを指定する方法について紹介してきました。キーワードの前に記号を付けることで AND, OR, NOT, MUST の意味を持たせることができました。

単独オプション

実は --le オプションで扱うそれぞれのキーワードは、個別の単独オプションで指定することもできます。一覧にすると、こうです。

記号意味単独オプション
なしAND or OPTIONAL-e, –and
-NOT-v, –not
?OR–or
+MUST-r, –must

このため、以下のコマンドは、どれも同じ意味になります。

greple 'まぐろ ?はまち ?えび -いくら' sushi.txt
greple 'まぐろ はまち|えび -いくら' sushi.txt
greple -e まぐろ --or はまち --or えび -v いくら sushi.txt
greple -e まぐろ -e 'はまち|えび' -v いくら sushi.txt

機能的に違いはないので、どれでも使いやすい方法で指定すればいいと思います。--or オプションに関しては、単独オプションで指定したものがグループ化されます。

絞り込み検索

単独オプションが便利なのは、次々にオプションを追加して、選択肢を絞り込んでいくような場合です。シェルのヒストリー機能を使って直前のコマンドを呼び出して、そのまま最後に追加していくことができます。

特に -v オプションは検索ワードを指定するオプションとしては解釈されないので、裸の(オプション指定なしの)検索ワードがあっても、最後に追加するだけで検索結果を絞り込むことが可能です。オプション引数とそれ以外の引数は、このように混在させることができます。

greple -n まぐろ sushi.txt
greple -n まぐろ sushi.txt -v いくら
greple -n まぐろ sushi.txt -v いくら -v いか
greple -n まぐろ sushi.txt -v いくら -v いか -v サーモン

実行してみるとこのような結果になります。

image.png

ちょうど、パイプで grep -v コマンドをつないでいくのと同じ要領で絞り込んでいくことができます。

毎回まぐろの色が変わってしまっているのは実装上の都合です。この結果を見て、修正した方がいいのではないかと感じていますが、この場合むしろ見やすくなっていいですね。そのうち直します。

-v オプションにも正規表現を使えるので、最後のコマンドは次のように書いても同じです。

greple -n まぐろ sushi.txt -v 'いくら|うに|たまご'

まとめ

複数キーワードの AND, OR, NOT, MUST 指定を単独のオプションで行う方法について紹介しました。--le オプションとどちらが適しているかは、好みや状況によって変わってくると思います。

grep 系のコマンドを使う状況では、最初に出た結果が多すぎて、どうやって絞り込んでいくか試行錯誤するようなことがよくあります。この場合、上で紹介した -v オプションの使い方は有効です。

オプションを最後にまとめて、こんな風に使うやり方もいいかもしれません。この場合は、パターンが最初の引数ではないのでオプション指定が必要ですが、--le の代わりに -x を使うこともできます。

greple sushi.txt -x 'まぐろ -いくら -いか -サーモン'

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
  3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
  4. https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703
  5. https://qiita.com/kaz-utashiro/items/24ac0b8fdd30b598e069
  6. https://qiita.com/kaz-utashiro/items/a1ba4e3d07cf37dc25e3

8 - 検索範囲指定 --inside/--outside

これはgrepleチュートリアルの8日目です。これまでに、複数キーワードを使って、様々なロジックで対象データから文字列を検索する方法を紹介しました。今回は、検索する対象の範囲を指定する方法について紹介します。

検索する場所を選びたい

今まで、寿司セットから好みのネタを探す方法について考えてきました。

image.png

しかし、一点どうも気に入らない部分があります。おわかりでしょうか。寿司ネタを検索しているのに、「まぐろづくしセット」というセット名がマッチしてしまっている点です。

それくらい別にいいじゃないかというかもしれませんが、まぐろづくしだからいいものの、これがもしまぐろ嫌いセットだったらどうでしょうか。まぐろ好きは激おこです。

このように、検索対象データの内容は一様ではないのに、一般の検索コマンドはそれを無視して全体を検索対象にしてしまいます。解決するためにはデータベースを使うとか、専用の検索コマンドを用意するなどの必要があります。

greple による検索範囲指定

greple には、検索範囲を指定する機能があります。まず、寿司セット名範囲を表すパターンを考えてみましょう。セット名部分は ^\S+ という正規表現でマッチすることができます。行頭から始まる空白以外の文字の連続という意味です。まずは、そのパターンを検索してみます。

image.png

うまく動いているようです。次に、この部分を --inside オプションとして指定して、まぐろを検索します。

greple --inside '^\S+' まぐろ sushi.txt

image.png

意図した通りに、セット名に含まれるまぐろだけが検索されました。

でも、求めているのはセット名に含まれないまぐろです。ですから、今度は --inside ではなくて --outside オプションとして指定します。

greple -n --outside '^\S+' まぐろ sushi.txt

image.png

これで、セット名以外の範囲にあるまぐろだけがハイライトされるようになりました。もちろん、セット名以外の部分にまぐろが含まれなければ、その行は表示されません。

繰り返し指定

--inside--outside は、繰り返し指定することができます。その場合、それぞれの範囲の和集合が検索対象範囲となります。

--inside--outside で同じ範囲を指定するとどうなるかというと、ある領域とその補集合の和になるので、当然全体になります。

greple --inside '^\S+' --outside '^\S+' まぐろ sushi.txt

image.png

このように、何も指定しないのと同じ部分がマッチしていますが、寿司セット名とそれ以外の部分で色が変わっています。greple は、複数の検索範囲が指定され、検索ワードが1つしかなかった場合、検索範囲毎にハイライトカラーを変えて表示します。

まとめ

--inside--outside オプションにパターンを指定することで、指定した領域の内側、あるいは外側だけに検索対象を限定する方法について紹介しました。

指定するパターンは、いくらでも複雑化することができます。たとえば、次のようにすれば、C のソースコードのコメント部分のみを対象にして検索することができます。/* で始まって */ で終わる最小範囲を指定しています。

greple --inside '(?s)/\*.*?\*/' pattern ...

次の例は、メールの Subject 行と本文のみを対象にして検索しています。今回のチュートリアルの中では正規表現そのものについて詳しく説明はしません。ちょっとトリッキーな表現になっているので、どうして動作するのか考えてみてください。

greple --inside '\A(.+\n)*\KSubject:.+' --outside '\A(?s:.*?)\n\n'

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
  3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
  4. https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703
  5. https://qiita.com/kaz-utashiro/items/24ac0b8fdd30b598e069
  6. https://qiita.com/kaz-utashiro/items/a1ba4e3d07cf37dc25e3
  7. https://qiita.com/kaz-utashiro/items/0c8c944c17a72724b771

9 - 検索範囲指定 --include/--exclude

これはgrepleチュートリアルの9日目です。前回--inside--outside オプションを使って、検索する対象の範囲を指定する方法について紹介しました。今回は、その続きで --include--exclude オプションについて紹介します。

例外条件を指定したい

--inside--outside は、全体の中から、どこを検索対象にするかという観点で使いました。それに対して --include--exclude は、どこを検索対象から外すかという観点で使います。

--outside オプションを使って、寿司ネタ領域からまぐろを検索しています。

image.png

でも、まぐろは好物だけど、ヅケはあまり好きではなくて、ネギも勘弁して欲しいなあということで、漬けまぐろねぎまぐろを除外したいと思いました。

この場合 --exclude オプションに除外したい文字列を与えることで、それに対するマッチを抑制することができます。

greple -n --outside '^\S+' まぐろ sushi.txt --exclude 漬けまぐろ --exclude ねぎまぐろ

image.png

ヅケとネギはハイライトされなくなりました。でも、選択肢は変わりませんでした。

文字列には正規表現を使用することができるので --exclude '(漬け|ねぎ)まぐろ' と書くこともできます。加えて、お子様セットも年齢制限があるので除外しましょう。この場合は単なる文字列ではなく、「お子様セット」ではじまる行全体を指定したいので ^お子様セット.* と指定します。

sh greple -n --outside '^\S+' まぐろ sushi.txt --exclude '(漬け|ねぎ)まぐろ' --exclude '^お子様セット.*' image.png

お子様セットは候補に出てこなくなりました。

–inside/–outside と –include/–exclude の使い分け

流れとしては --inside/--outside で検索対象範囲を拾い出して、--include/--exclude で絞り込むという使い方になります。

上の例で、--exclude の代わりに --outside を使うことはできません。前回書いたように --inside--outside で指定した範囲は和集合として扱われるので、結果として全体に戻ってしまいます。

この例では、--outside を一度しか使っていないので、そこを --exclude にしても結果は変わりません。単独で使う場合は、どちらを使っても同じ結果になります。

まとめ

前回の --inside/outside に加えて --include/exclude オプションについて紹介しました。

TeX や roff など、マークアップを使った文書ファイルを校正しようとする場合、マークアップ命令やコメント部分は対象から外して、純粋に文章の部分だけを処理する必要があります。

また、原稿の中には自分で書いた文章以外に、引用文であったり、別の文書や書籍のタイトル、固有名詞など、ローカルなルールを適用すべきではない部分もあります。それらを例外として処理対象から外すことができないと実用的なツールとはなりません。greple の機能は、そのような経験から進化してきました。

greple のオプションは、なるべく grep に合わせるようにしているのですが、--include--excude については、まったく違う意味になるので注意してください。

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
  3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
  4. https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703
  5. https://qiita.com/kaz-utashiro/items/24ac0b8fdd30b598e069
  6. https://qiita.com/kaz-utashiro/items/a1ba4e3d07cf37dc25e3
  7. https://qiita.com/kaz-utashiro/items/0c8c944c17a72724b771
  8. https://qiita.com/kaz-utashiro/items/8783c2fd0cc4315b9a3d

10 - 検索ブロック指定

一般的に、grep 系のツールが検索の対象とするのは「行」です。しかし、扱いたい情報の単位は行とは限りません。greple は、検索対象とするデータの単位を柔軟に指定することができます。

–all

--all は、ファイル全体を検索単位とするオプションです。

このオプションが有効なのは、当たり前ですが、ファイルの内容を全部見たい場合です。

寿司セットの中には魚介類以外のネタとして「サラダ」「アボカド」「うどん」があって、すべてを AND で指定すると、そのすべてを含むセットはありませんが --all を指定すれば全体を眺めることができます。

image.png

対象が原稿であれば、注目する部分をハイライトして、全体を眺めたいような場合に有効です。

ファイル名のみを表示する -l オプションと組み合わせて使用すると、指定したワードをすべて含むファイルを探すことができます。検索エンジンと同じような使い方です。

image.png

-p, –paragraph

-p (--paragraph) オプションを指定すると、行ではなく、空白行で区切られたパラグラフを単位として検索を行います。複数キーワードの処理も、行ではなくパラグラフ単位で行われるので、指定したワードは同一行に含まれる必要はありません。

次の例では AND, OR, NOT, MUST という単語がすべて含まれるパラグラフを検索しています。

image.png

デフォルトでは、ファイル名は grep と同様にすべての行に表示されますが、--filestyle=once というオプションを指定することで、最初に一度だけ表示しています。

–block

--block オプションでパターンを指定すると、それにマッチする部分が検索単位となります。次の例では git のソースコードから、Cのコメント部分 (/*...*/) をブロックとして指定して UTF, Unicode, BOM という単語がすべて含まれるブロックを検索しています。

greple --border '(?s)/\*.*?\*/' --fs=once -i 'utf unicode bom' *.h

image.png

この場合、検索対象のブロックは連続していません。ブロックに相当しない場所でのマッチは無視されます。

–border

--border オプションには --block と同じようにパターンを指定して、それを元にブロックを作りますが、--block と違い、マッチの始点と終点を境界とする連続したブロックを作ります。

デフォルトの行単位での挙動は --border=^ を指定したのと同じで、パラグラフモードは連続する改行文字 --border='\n\n+' を指定したのと同じです1

次の例は、シャープ (#) で始まる行の行頭にブロック境界を設定します。つまり、# ではじまる行から次の行頭の # までの、マークダウン形式のパラグラフがブロックとなります。

greple --border '^(?=#)' PCRE *.md --fs=once

image.png

-A, -B, -C

-A (after), -B (before), -C (context) オプションは、検索行の前後を同時に表示するためのもので、grep とほぼ同様に使うことができます。次の例は、マッチした前後1行ずつを表示しています。

greple -n -e びんちょう sushi.txt -C1

image.png

この前後コンテキストも、指定したブロックに対して適用されます。ですから、パラグラフモードであれば、前後のパラグラフを一緒に表示します2

image.png

この時、検索ロジックもコンテキスト同様に拡張されます。次の例で、最初のコマンドではびんちょうサラダを両方含むセットは見つかりませんが、次のコマンドは -C1 でコンテキストを前後に1行ずつ拡張することで、条件を満たすデータが発見されます。

greple -n -e びんちょう -e サラダ sushi.txt
greple -n -e びんちょう -e サラダ sushi.txt -C1

image.png

まとめ

greple の検索単位を指定するブロック機能について紹介しました。テキストファイルであっても、行単位で情報が管理されていることはむしろ稀です。処理対象の情報単位を柔軟に設定することで、論理的に意味のあるデータブロックに対して検索等の操作をすることが可能になります。

今回紹介した単純なパターンマッチによる方法では処理できないような複雑なデータ形式もあります。そのような場合には、また別のアプローチがあります。

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
  3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
  4. https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703
  5. https://qiita.com/kaz-utashiro/items/24ac0b8fdd30b598e069
  6. https://qiita.com/kaz-utashiro/items/a1ba4e3d07cf37dc25e3
  7. https://qiita.com/kaz-utashiro/items/0c8c944c17a72724b771
  8. https://qiita.com/kaz-utashiro/items/8783c2fd0cc4315b9a3d
  9. https://qiita.com/kaz-utashiro/items/84f5a6be6bf996076c64

  1. 簡略化して書いています。実際に使っているパターンは (?:\A|\R)\K\R+ というものです。 ↩︎

  2. -C オプションのデフォルトは2です。-p オプションを使った場合、空白行の部分も1パラグラフを構成します。したがって、このように前後1パラグラフずつを表示しているように見えます。 ↩︎

11 - 拡張モジュールの使用法

greple の特徴の一つは、モジュールによって拡張可能なことです。今回は、モジュールの使い方について紹介します。

利用可能なモジュールを表示する

モジュールは -M オプションで指定します。単独で使用すると、利用できるモジュールを表示します。この中には、greple に標準で含まれるものと、別パッケージからインストールしたもの、プライベートに作成したものが含まれます。

$ greple -M
Use -M option at the beginning with module name.
Available modules:
	dig
	find
	line
	perl
	pgp
	select
	subst
	autocolor
	i18n
	termcolor

greple の拡張モジュールは、App::Greple の下にある小文字ではじまる Perl モジュールです。大文字ではじまるものは greple そのものを実装するためのものです。

greple の拡張モジュール機能は Getopt::EX モジュールで実現されており、App::Greple に加えて Getopt::EX の下にある汎用のモジュールを使うこともできます。i18n, termcolor などは Getopt::EX のモジュールです。

モジュールを呼び出す

-M オプションにモジュール名を指定することで、そのモジュールを呼び出すことができます。次の例は App::Greple::find モジュールを使うことを指示していますが、greple の拡張モジュールとして使用する場合には、単に -Mfind と指示します。

greple -Mfind

マニュアルを表示する

モジュールオプションに続いて --help オプションを指定することで、そのモジュールのマニュアルを表示することができます。

$ greple -Mfind --man
NAME
    find - Greple module to use find command

SYNOPSIS
    greple -Mfind find-options -- greple-options ...

DESCRIPTION
    Provide find command option with ending '--'.

    Greple will invoke find command with provided options and read its output
    from STDIN, with option --readlist. So

        greple -Mfind . -type f -- pattern

    is equivalent to:

        find . -type f | greple --readlist pattern

    If the first argument start with `!', it is taken as a command name and
    executed in place of find. You can search git managed files like this:

        greple -Mfind !git ls-files -- pattern

ただ、実装上の都合で、別のモジュールのマニュアルが表示されてしまうことがあります。その場合は、man コマンドや perldocApp::Greple に続いてモジュール名を指定します。

man App::Greple::find
perldoc App::Greple::find

ちなみに、--man の代わりに --show を使うと、モジュールの内容を見ることができます。perldoc -m としても同じです。

モジュールを使う

モジュールの使い方について finddig モジュールを例に説明します。

greple には grep -r のようにディレクトリの下を再起的に検索するオプションはありません。その代わりに --readist というオプションがあって、標準入力から読んだファイル名を検索対象とします。find コマンドの出力を --readlist オプションで読み込めば再起的な検索が可能です。

find . -type f | greple --readlist Copyright

find モジュールを使うと、greple コマンドのオプションとして find オプションを指定することができるようになります。-Mfind から -- までの間の引数を find コマンドのオプションとして処理します。

greple -Mfind . -type f -- Copyright

find コマンドのオプションは非常に詳細な指定が可能ですが、使いこなすのにはちょっとコツが必要です。たとえば .git ディレクトリを検索対象から外すためには次のように指定します。あまり直感的ではなくて、-prune オプションの使い方はいつもわからなくなります。

find . -name .git -prune -o -type f

git だけではなく様々なケースに対応しようとすると、オプションはさらに複雑化してきます。dig モジュールは find モジュールの面倒なオプションを自動的に設定して、必要のないリポジトリや画像ファイルなどをスキップするためのモジュールです。次のように使うことができます。

greple -Mdig Copyright --dig .

このコマンドは、実際には次のようなオプションに展開されて実行されます。

greple -Mfind .
( ( ( -name .git -o -name .svn -o -name RCS -o -name CVS ) -o ( -name .vscode ) -o ( -name .build -o -name _build ) ) -prune -o -type f )
! -name .* ! -name *,v ! ( -name *~ -o -name *.swp )
! ( -iname *.jpg -o -iname *.jpeg -o -iname *.gif -o -iname *.png -o -iname *.ico -o -iname *.heic -o -iname *.heif -o -iname *.svg )
! ( -iname *.tar -o -iname *.tar.gz -o -iname *.tbz -o -iname *.tgz -o -name *.a -o -name *.zip )
! -iname *.pdf ! ( -name *.db -o -iname *.bdb )
! ( -name *.bundle -o -name *.dylib -o -name *.o -o -name *.fits )
-print --

これを手で入力することを考えると気が遠くなりそうです。

dig モジュールには --git というオプションも定義されていて、git ls-files の結果に対して検索をかけることができます。

まとめ

今回は greple のモジュール機能について、その使い方を紹介しました。greple には、これまで紹介していないオプションが数多くありますが、モジュールを使うことで、複雑なオプション指定を組み合わせてシンプルなインタフェースを提供することが可能になります。モジュールの作り方については、機会を改めて説明します。

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
  3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
  4. https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703
  5. https://qiita.com/kaz-utashiro/items/24ac0b8fdd30b598e069
  6. https://qiita.com/kaz-utashiro/items/a1ba4e3d07cf37dc25e3
  7. https://qiita.com/kaz-utashiro/items/0c8c944c17a72724b771
  8. https://qiita.com/kaz-utashiro/items/8783c2fd0cc4315b9a3d
  9. https://qiita.com/kaz-utashiro/items/84f5a6be6bf996076c64
  10. https://qiita.com/kaz-utashiro/items/ebc7ea99f800cfc8c90c

12 - 初期設定ファイル .greplerc

greple は、UNIX の他の多くのコマンドと同様に、ホームページに初期設定ファイル (~/.greplerc) を用意することで、起動時にそれを読み込むことができます。この中では、様々な設定が可能です。

default: デフォルトオプション

option 命令で新しいオプションを定義することができます。中でも default という名前は特別で、実行時に自動的に付与するオプションを指定することができます。たとえば、次のように設定すると、ハイライトモードが常に有効になります。

option default --color=always

さらに、行番号を表示させたければ、このようにします。default の定義が複数行あった場合には、最後の定義だけが有効になります。

option default --color=always -n

option: オリジナルオプション

自分でオリジナルのオプションを定義することもできます。次のように設定しておけば --sushi と書くだけで、そこに定義したオプション指定したことになります。

option --sushi --outside '^\S+' --exclude '^お子様セット.*'

image.png

-do はデバッグ用のオプションで、最終的に実行されるオプションを表示します。

define: マクロ定義

複雑なオプションを定義する際には、マクロによる文字列置換を使用することができます。

define {base03}  #002b36
define {base02}  #073642
define {base01}  #586e75
define {base00}  #657b83
define {base0}   #839496
define {base1}   #93a1a1
define {base2}   #eee8d5
define {base3}   #fdf6e3
define {yellow}  #b58900
define {orange}  #cb4b16
define {red}     #dc322f
define {magenta} #d33682
define {violet}  #6c71c4
define {blue}    #268bd2
define {cyan}    #2aa198
define {green}   #859900

option  --solarized \
        --cm {yellow}  \
        --cm {orange}  \
        --cm {red}     \
        --cm {magenta} \
        --cm {violet}  \
        --cm {blue}    \
        --cm {cyan}    \
        --cm {green}

autoload: モジュールの自動読み込み

autoload は、モジュールを自動的に読み込むための命令です。次の設定は --dig および --git オプションは dig モジュールで定義されていることを指示します。--dig オプションは -Mdig --dig に展開され、dig モジュールが自動的に読み込まれます。

autoload -Mdig --dig --git

__PERL__: 任意コードの実行

.greplerc の中に __PERL__ という文字列があると、それより後の内容を Perl プログラムとして評価します。

greple のオプションの中には、任意の関数を呼び出すことができるものがあります。たとえば --begin オプションを使うと、ファイルを検索する前にその内容に対して行う処理を指定することができます。

.greplerc に次のようなコードを用意したとします。

__PERL__
sub remove_header {
    s/\A---\n(.+\n)+---\n\n*//;
}

すると、次のようにして、マークダウンファイルを検索する前に、ヘッダ部分を削除することができます。

greple --begin '&remove_header' *.md

他の言語にも対応できるように、このような形式にしていますが、今のところ対応しているのは Perl だけです。

まとめ

greple の初期設定ファイル .greplerc について紹介しました。

オプションを組み合わせることで、様々なタイプのデータに対応する複雑な処理を実現することができますが、どうしてもコマンド行が複雑化してきます。.greplerc に自分でよく使うオリジナルオプションを定義することで、作業を効率化することができます。

デフォルトオプションについては、.greplerc に記述する以外に、GREPLEOPTS という環境変数を設定する方法もあります。

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
  3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
  4. https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703
  5. https://qiita.com/kaz-utashiro/items/24ac0b8fdd30b598e069
  6. https://qiita.com/kaz-utashiro/items/a1ba4e3d07cf37dc25e3
  7. https://qiita.com/kaz-utashiro/items/0c8c944c17a72724b771
  8. https://qiita.com/kaz-utashiro/items/8783c2fd0cc4315b9a3d
  9. https://qiita.com/kaz-utashiro/items/84f5a6be6bf996076c64
  10. https://qiita.com/kaz-utashiro/items/ebc7ea99f800cfc8c90c
  11. https://qiita.com/kaz-utashiro/items/25a14e75380c39b5e0af

13 - カラーオプション

greple は、複数のハイライトカラーを使って結果を表示することができます。これまで紹介したような、検索キーワードの色分け以外にも、様々な色の指定が可能です。今回は、色の指定方法について紹介します。

カラーマップ

greple の色情報はカラーマップで管理され、その中にはインデックスリストと名前付きのリストという2種類の要素があります。つまり、リストとハッシュです。

-dc というデバッグオプションを使うと、カラーマップ情報を見ることができます。デフォルトのカラーマップはこうです。

image.png

最初に表示されているのが名前付きリストで、ファイル名 (FILE) や行番号 (LINE) の表示色に関する情報を保持しています。

次にあるのがインデックスリストで、検索した文字列をハイライトするために使われます。

–colormap, –cm オプション

カラーマップは --colormap オプションで指定します。ちょっと長いので --cm と省略することもできます。デフォルトのカラーマップは、次のように指定したのと同じです。

--cm BLOCKEND=/WE,FILE=G,LINE=Y,PROGRESS=B,TEXT= \
--cm 000D/544,000D/454,000D/445 \
--cm 000D/455,000D/545,000D/554 \
--cm 000D/543,000D/453,000D/435,000D/534,000D/354,000D/345 \
--cm 000D/444,000D/433,000D/343,000D/334 \
--cm 000D/344,000D/434,000D/443,000D/333

1行目の名前付きのリストは NAME=color という形式、2行目以下のインデックスリストはラベルなしの color だけです。複数の要素をカンマで区切って同時に指定することができます。--cm オプションは繰り返し使うことができるので、上の例では分けて書いてありますが、1つにまとめてしまっても構いません。

簡単に説明すると、G (Green), Y (Yellow) などの基本の色、D (ボールド) のような効果、544 のように 0-5 の数字3桁で表された216色で指定されています。スラッシュ (/) の左がフォアグラウンド、右側はバックグラウンドカラーです。

色の指定

基本 16色

    R  r   Red
    G  g   Green
    B  b   Blue
    C  c   Cyan
    M  m   Magenta
    Y  y   Yellow
    K  k   Black
    W  w   White

大文字は、赤、緑、青、シアン、マジェンタ、黄、黒、白の基本の8色です。小文字は代替色を意味しますが、多くの端末では基本色よりも明るい色が指定されています。

RGB 6x6x6 216色

    000 .. 555         : 6x6x6 RGB 216 colors

RGB 値を0から5の数字で表した216色です。

慣れると案外わかりやすくて、555は白、R以外を0にして500なら原色の赤。GとBの値を増やすと白に近づいて544は淡い赤という具合です。RGB と CMY のポジションが対応していて、R の部分を落とした055は、補色のシアン、Bを落として550なら黄色になります。1つだけ大きければ RGB、1つだけ小さければ CMY と憶えるとわかりやすいと思います。

基本のカラーマップは RGB に 543 のどれかを当てた組み合わせをバックグラウンドカラーとしています。

グレースケール 24色

L01 から L24 は、24階調のグレースケールです。L00 は黒 (000)、L25 は白 (555) と同じです。Ww は、真っ白とは限りません。

    L00 .. L25         : Black (L00), 24 grey levels, White (L25)

12ビット/24ビット RGB

RGB を10進や16進の、12ビット値あるいは24ビット値で指定することもできます。ただし、256色表示の端末では表示できないので、その場合は近似する216色に変換して表示します。

    (255,255,255)      : 24bit decimal RGB colors
    #000000 .. #FFFFFF : 24bit hex RGB colors
    #000    .. #FFF    : 12bit hex RGB 4096 colors

名前

https://en.wikipedia.org/wiki/X11_color_names で定義されている名前で色を指定することができます。

    <red> <blue> <green> <cyan> <magenta> <yellow>
    <aliceblue> <honeydue> <hotpink> <mooccasin>
    <medium_aqua_marine>

効果

色以外の効果を指定することもできます。よく使うのはボールド(D)、イタリック(I)、アンダーライン(U)、反転(S)あたりでしょうか。見えなくする H や、見え消し線を引く X はサポートされていない端末もありますが、使い方によっては効果的です。点滅(F)は面白いけど、うるさいのであまり使いません。早い点滅 (Q) をサポートしている端末は見たことがありません。

    N    None
    Z  0 Zero (reset)
    D  1 Double strike (boldface)
    P  2 Pale (dark)
    I  3 Italic
    U  4 Underline
    F  5 Flash (blink: slow)
    Q  6 Quick (blink: rapid)
    S  7 Stand out (reverse video)
    H  8 Hide (concealed)
    X  9 Cross out
    E    Erase Line

    ;    No effect
    /    Toggle foreground/background
    ^    Reset to foreground

行消去の E は特殊で、文字の属性を定義するものではありません。これを指定すると、色設定のシークエンスと同時に、カーソルがある場所から行末までを消去するシークエンスを出力します。文字を消すのと同時に背景色で埋めるので、その色の線が引かれたように見えます。最初の例の BLOCKEND で使われています。

ANSI 256色 ターミナルカラー

標準的な256色表示のANSI端末は、これまでに説明した基本の16色、6階調の RGB 216色、24階調のグレースケールを表示することができます。これは、次のコマンドで一覧することができます。

perl -MGetopt::EX::Colormap=:all -E colortable

image.png

image.png

フルカラーターミナル

24ビットフルカラーに対応している端末では、フルカラーの指定をそのまま出力することができます。Apple の標準ターミナルは256色表示ですが、iTerm2 などはフルカラー表示が可能です。greple は、COLORTERM という環境変数に truecolor という値が設定されていると、フルカラー端末であると認識します。

まとめ

greple は、複数の色を扱えることが特徴の1つです。しかし、色の指定が煩雑だと使いこなすのが難しいので、シンプルで統一的な方法で指定できるように工夫しています。現在は、色を管理する部分を切り出して Getopt::EX::Colormap という独立したモジュールでリリースしています。

SEE ALSO

https://qiita.com/advent-calendar/2021/greple

  1. https://qiita.com/kaz-utashiro/items/5b6bcbe54891b3bd9db5
  2. https://qiita.com/kaz-utashiro/items/eb8c7067e6de34842fe3
  3. https://qiita.com/kaz-utashiro/items/165e744d4250adedc4c1
  4. https://qiita.com/kaz-utashiro/items/439e6abcecf36c520703
  5. https://qiita.com/kaz-utashiro/items/24ac0b8fdd30b598e069
  6. https://qiita.com/kaz-utashiro/items/a1ba4e3d07cf37dc25e3
  7. https://qiita.com/kaz-utashiro/items/0c8c944c17a72724b771
  8. https://qiita.com/kaz-utashiro/items/8783c2fd0cc4315b9a3d
  9. https://qiita.com/kaz-utashiro/items/84f5a6be6bf996076c64
  10. https://qiita.com/kaz-utashiro/items/ebc7ea99f800cfc8c90c
  11. https://qiita.com/kaz-utashiro/items/25a14e75380c39b5e0af
  12. https://qiita.com/kaz-utashiro/items/ebbeb8a5538a15ff04fc

14 - カラーオプション(続き)

色についてもっと色々

前回は、カラーマップを指定する --colormap オプションと、色の指定の仕方について紹介しました。今回は、色を扱う様々なオプションについて紹介します。

–colormap

greple のカラーマップには、名前付きカラーと、インデックスカラーの2種類があり、どちらも --colormap (--cm) オプションで設定することができました。今回紹介するのは、マッチしたパターンをハイライトするために使用されるうインデックスカラーに関するものです。

–regioncolor, –ri

以前に、複数の検索範囲を指定すると、それぞれの領域に別の色が割り当てられる例を紹介しました。

greple -n --inside '^\S+' --outside '^\S+' '[ー\p{Katakana}]+' sushi.txt

image.png