3

各レコードに関する特定の情報を引き出すために、入力を検索しています。悲しいことに、各レコードは複数の行に分散しています。たとえば、(簡略化された抜粋)

01238584 (other info) more info, more info
[age=81][otherinfo][etc, etc]

私が本当に気にかけているのは、識別子と年齢(例では0123858481)だけです。明確にするために、これらの2つの線に近づくために入力で確実に検索できる唯一の正規表現は、

\[age=[0-9]+\]

...そしてもちろん、その上の行から識別レコード番号と一緒にその年齢を印刷したいと思います。

 01238584   81

私のすべてのシステム管理者シェルの経験とまともなawkの習得で、私はまだ解決策を思い付いていません。もちろんgrep -B1、各行のセットを取得するために使用できますが、それではどうしますか?私はいつもこれらの種類のものにawkを使用します...しかし、関連するデータは常に同じ行にあります。ため息これは間違いなく私の現在のawkスキルを超えています。

読んでくれてありがとう。ポインタがありますか?


編集
チャーリーの提案と、これまで行ったことのないawkのレコードセパレーターの変更を行います。きれいではありませんが、入力もきれいではありません。仕事は終わりました。

egrep -B1 '\[age=[0-9]+\]' inputfile |
awk '
  BEGIN{ RS = "--" }
  { printf "%s  %s\n", $1, gensub(/.*\[age=([0-9]+)\].*/, "\\1", 1) }'
4

2 に答える 2

4

入力ファイルをもっと表示できますか?たとえば、データレコードが空白行で区切られている場合、AwkのRS特殊変数を使用してレコード区切り文字を変更し、複数の行を1つのレコードとして処理することができます。(たとえば、http://www.staff.science.uu.nl/~oostr102/docs/nawk/nawk_19.htmlを参照してください)

いずれにせよ、私はあなたのすべてのデータレコードを1行または1つの論理レコードに入れる何かをしたいと思うでしょう。

それができないが、レコードIDが常にageタグの前の行にあることがわかっている場合は、Pythonでreadlinesを使用して簡単に行うことができます。これにより、ファイル全体が行のリストに読み込まれます。

 with open("file.dat") as f:
     lines = f.readlines()
     for ix, line in enumerate(lines):
         if # line has age field
            # get record from lines[ix-1]

または、もちろん、Awkの前の行をいつでもメモリに保持できます

 BEGIN { prevline = "" }
       { # process the line
         prevline = $0
       }
于 2012-07-29T05:47:48.543 に答える
2

このような場合、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
----------------------------------------------------------------------
于 2012-07-29T14:43:19.940 に答える