複数行の正規表現を簡単に検索して置換できるコマンドラインツール

複数行の正規表現を簡単に検索して置換できるコマンドラインツール

私はテキストエディタを使用するときに検索と置換にPCRE正規表現を頻繁に使用しますが、次のような強力なUnixコマンドラインツールで検索と置換perlにPCRE正規表現が使用されることを知っていて、非常に速いです。正規表現は非常に複雑で、あらゆる状況で覚えにくいあらゆる種類の構文が必要です。awksed

より複雑な複数行の正規表現を使用して検索および置換する作業(ファイル全体のすべての項目について)を次のように簡単に実行できるLinux用のコマンドラインツールはありますか?

magicregextool 's/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/' file.txt

つまり、一致させる正規表現は、テキストエディタのフィールドに入力したものと同じですsearch for。代替文字列は複数行の正規表現も処理でき、複雑な構文は必要ありません。

編集する:

リクエストに応じて入力を添付し、上記の正規表現の例を使用して実際に実行したいことを説明します。

次のように入力してください。

2016-05-16 06:17:00 > foobar joined the channel.
2016-05-16 06:17:13 <foobar> hi
2016-05-16 06:18:30 > foobar was kicked from channel.
2016-05-16 06:18:30 > foobar disconnected
2016-05-16 06:20:13 > user joined the channel.
2016-05-16 06:20:38 <user> bye
2016-05-16 06:21:57 > user disconnected

次の出力を生成する必要があります。

2016-05-16 06:17:00 > foobar joined the channel.
2016-05-16 06:17:13 <foobar> hi
2016-05-16 06:18:30 > foobar was kicked from channel.
2016-05-16 06:18:30 > foobar disconnected
2016-05-16 06:20:38 <user> bye
2016-05-16 06:21:57 > user disconnected

正規表現は埋め込み行と一致し、[username] joined the channelその下に含まれる行を探します。[username] disconnected 〜しない限りこれらの2行の間にはorがあります[username] was kicked from channel.[username] was banned from channel.

次に、置換文字列は、対応する行の後のすべての行を一致するパターンで置き換え、上記[username] joined the channelの入力からその行を効果的に削除します。2016-05-16 06:20:13 > user joined the channel.

おそらくあなたにはあまり意味がないでしょうが、これは私が最近作業したのと似た正規表現のサンプルです。私はこの特定の問題や上記のUnixツールに関連する同様の問題に対する解決策を探しているわけではないことに注意してください。変更されていない「検索」を使用し、テキストエディタ(特にGeany、しかし重要ではない)で使用される文字列を複雑な構文や追加なしで使用できるコマンドラインツールを探しています。処理するプログラミングロジック複数行の「検索」と文字列の置き換え。

ベストアンサー1

ここでPerlがなぜ許可されないのかわかりません。提供された入力に基づいて、この行は要求された出力を提供します。

perl -0777p -e 's/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/mg' irc.txt

このパラメータは、正規表現修飾子を追加したことを除いて、-eまさに最初のパラメータです。これは「未修正」ではないかもしれませんが、不合理に見えません。行全体を入力したくない場合は、このスクリプトを次のように書くことができます。magicregextool/mgmagicregextool

#!/usr/bin/perl -0777p
BEGIN { $::arg = shift @ARGV; }
eval $arg;

でも:

#!/bin/sh
perl -0777pe $*

次に、次のように入力します。

magicregextool 's/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/mg' irc.txt

これは例と同じです(修飾子の追加を除く/mg)。

もう1つの利点は、各ファイルに対して複数の関連検索/置換操作を実行している場合は、そのタスクを同じスクリプトに入れることができることです。

#!/usr/bin/perl -0777p
s/.* > (.*) joined the channel\.\n(((?!.* \1 (was kicked from channel\.|was banned from channel\.)\n).*\n)+?.*\1 disconnected)/\2/mg;
s/(some other\n)matched text/\1/mg;

おすすめ記事