このような場合、Perlは簡単に友達として機能できます。ファイル全体をメモリに読み込んで、複数行に正規表現を適用できます。入力レコード区切り文字を設定する0777
と、このような「スラーピング」アクションが発生します。スイッチは-n
、コマンドラインで提供された1つまたは複数のファイルを読み取るように指示するだけです。-e
スイッチの引数は、実行するコードを構成します。
正規表現の/s
修飾子を使用.
すると、改行を一致させることができます。\m
修飾子を使用すると、埋め込み改行の直前と直後の両方とを一致させること^
ができます。$
これらは、複数の論理行を含む文字列を解析するための鍵です。修飾子は/g
、すべての一致をグローバルに検索するように正規表現エンジンに指示します。
perl -0777 -ne 'print "$1 $2\n" while m{^(\S+).+?\[age=(\d+)\]}gms' file
次のような入力ファイルがあるとします。
01238584 (other info) more info, more info
[age=81][otherinfo][etc, etc]
98765432 (still other info) still more info, and more info
[age=82][and more otherinfo][etc, etc, ad infinitum]
...上記のスクリプトは次のように出力します。
01238584 81
98765432 82
このようにして正規表現を分析できます。
perl -MYAPE::Regex::Explain -e 'print YAPE::Regex::Explain->new(qr/m{^(\S+).
+?[age =(\ d +)]} gms /)-> Explain() '
The regular expression:
(?-imsx:m{^(\S+).+?\[age=(\d+)\]}gms)
matches as follows:
NODE EXPLANATION
----------------------------------------------------------------------
(?-imsx: group, but do not capture (case-sensitive)
(with ^ and $ matching normally) (with . not
matching \n) (matching whitespace and #
normally):
----------------------------------------------------------------------
m{ 'm{'
----------------------------------------------------------------------
^ the beginning of the string
----------------------------------------------------------------------
( group and capture to \1:
----------------------------------------------------------------------
\S+ non-whitespace (all but \n, \r, \t, \f,
and " ") (1 or more times (matching the
most amount possible))
----------------------------------------------------------------------
) end of \1
----------------------------------------------------------------------
.+? any character except \n (1 or more times
(matching the least amount possible))
----------------------------------------------------------------------
\[ '['
----------------------------------------------------------------------
age= 'age='
----------------------------------------------------------------------
( group and capture to \2:
----------------------------------------------------------------------
\d+ digits (0-9) (1 or more times (matching
the most amount possible))
----------------------------------------------------------------------
) end of \2
----------------------------------------------------------------------
\] ']'
----------------------------------------------------------------------
}gms '}gms'
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------