sedやgrepの代替として使えるpurlを作りました

2024/04/13に公開1

作りました。

https://github.com/catatsuy/purl

Go製です。

何で作ったのか、どういう機能があるのか簡単に紹介します。

これまでの課題

sedやgrepには以下の問題があります。

  • 正規表現の記法がPerl互換ではなく、使いにくい
  • sedはmacとLinuxで互換性がなく(BSDとGNUで互換性がない)、OS依存のコードになりやすい

これまでその問題を避けるために私はPerlのワンライナーを利用してきました。Perlは正規表現が使いやすく、柔軟な指定もできます。OS依存にもなりにくいです。しかしPerlには以下の問題がありました。

  • 最近のmacやLinuxにはデフォルトでinstallされていないので使いにくい
    • 特にDockerのようなコンテナ環境は顕著
  • 最近は利用例が減っているので敬遠されがち
  • ワンライナー専用ツールではないのでオプション名がわかりにくい

そこで以下のツールを求められていると思います。

  • Perl互換の使いやすい正規表現が利用できる
  • OS依存にならない
  • 軽量でinstallが簡単
  • オプション名が分かりやすい

そこでpurlを作りました。

purlの特徴

  • 標準入力やファイルなど柔軟に渡せる
    • 出力も標準出力・ファイルを柔軟に選べる
  • 柔軟でわかりやすいオプションで利用できる
    • -replace -filter -excludeのような明確なオプション名
  • -overwriteオプションでファイル自体を上書きすることができる
  • -filterオプションはターミナルに出力する時は自動で色付けしてくれる
    • -color -no-colorオプションで指定することもできる

デモ

GitHubに動画を貼っています。

https://github.com/catatsuy/purl?tab=readme-ov-file#demo

インストール

macとLinux用のバイナリを配布しています。Goの開発環境が利用できるならgo installでもinstallできます。GitHubを参照してください。

https://github.com/catatsuy/purl?tab=readme-ov-file#installation

名前の由来

「Purl」という名前は、編み物の技術と流れる川の音にインスピレーションを得ています。編み物で「パール」とは、繰り返しの手法で滑らかな布を作ることです。川の音も連続的で落ち着いた流れが特徴です。「Purl」は、このツールがテキストの変換をスムーズに行い、繰り返しや流れのように途切れることなく作業を助けることを表しています。

(ChatGPTに相談して付けてもらいました)

使用例

変更を適用する前にプレビュー

purl -replace "@search@replace@" yourfile.txt

このコマンドはyourfile.txt内で"search"を探し、"replace"で置き換えられる様子を表示しますが、ファイル自体は変更しません。

ファイルを直接変更

purl -overwrite -replace "@search@replace@" yourfile.txt

-overwriteオプションを使用すると、Purlはyourfile.txt内の"search"を"replace"に置き換え、変更をファイルに保存します。

標準入力の使用

Purlは他のコマンドからの入力をパイプで受け取り、柔軟に使用することができます:

cat yourfile.txt | purl -replace "@search@replace@"

これはyourfile.txtの内容をPurlに送り、指定された置換パターンに従って変更されたテキストを表示します。

複数のファイルの使用

Purlは一度に複数のファイルを処理することをサポートしており、複数のドキュメントにわたって操作を適用できます。コマンドの最後にファイルをリストするだけです。

purl -replace "@search@replacement@" file1.txt file2.txt file3.txt

このコマンドはfile1.txtfile2.txtfile3.txtに対して置換操作を適用します。

-filterの使用

purl -filter "error" yourlog.log

このコマンドはyourlog.log内の"error"を含む行をフィルタリングし、より良い可視性のために色付きで表示します。

複数の基準で入力をフィルタリング

複数の基準に合致する行をフィルタリングするには、-filterオプションを複数回使用します。これはファイルから読み取る場合と標準入力を処理する場合の両方で機能します。

purl -filter "error" -filter "warning" yourlog.log

または標準入力で:

cat yourlog.log | purl -filter "error" -filter "warning"

これにより、yourlog.logから"error"または"warning"を含む行が表示されます。

複数のパターンに合致する行を除外

同様に、複数のパターンに合致する行を除外するには、-excludeを複数回指定します:

purl -exclude "debug" -exclude "info" yourlog.log

またはパイプ入力で:

cat yourlog.log | purl -exclude "debug" -exclude "info"

この方法では、"debug"または"info"を含む行が出力から除外されます。

大文字小文字を区別しない検索の使用

-iオプションを使用すると、Purlはフィルターや除外において大文字小文字を区別せずに一致させることができます。

purl -i -filter "error" yourfile.txt

このコマンドはyourfile.txtで'error'という単語を含む行を、'Error', 'ERROR', 'error'などのケースバリエーションで一致させます。

git grepとxargsを組み合わせる

Gitリポジトリ内の複数のファイルに変更を適用する場合、次の手順を使用します。

git grep -l 'search_pattern' | xargs purl -overwrite -replace "@search_pattern@replace_text@"

'search_pattern'を含むすべてのファイルを見つけ、Purlを使ってそれを'replace_text'に置き換え、変更を直接ファイルに適用します。

最後に

ファイルを適当に書き換える用途でも以下のように直感的に利用できて便利です。

https://github.com/catatsuy/private-isu/pull/473/files

結構便利だと思うので、使ってみてもらえたら嬉しいです。よろしくお願いします。

Discussion

kkddkkdd

こんにちは。
grep には perl 拡張オプション付きなので、sed でも同様になるならば、相当改善されるだろうとも思いました(sed では改行出力にも苦労しますし)。本題から離れて失礼しました。