LoginSignup
0
1

More than 5 years have passed since last update.

sedでメールヘッダーの継続行を一行にまとめる

Last updated at Posted at 2016-10-11

はじめに

1メール1ファイルの状態で、To:やCc:に特定のメールアドレスを含むものだけ抽出したいとか、ときかくFrom:行だけ全部取り出したいとかやろうとすると、ヘッダーの継続行の扱いがけっこう面倒くさいですね。

普通ならPerlやPythonで書けばよいのだろうけれど、sed で継続行を一行にまとめる処理を書いてみました。

sedは読み込んだ行はパターンスペースに配置して、このパターンスペースが操作の対象となりますが、もうひとつホールドスペースというのを持っていて、これをうまく使うことで複数行を処理できます。

サンプルコード

:top
/^$/q
/^[A-Za-z]/{
/^[Ff][Rr][Oo][Mm]:/b concat
/^[Tt][Oo]:/b concat
/^[Cc][Cc]:/b concat
b next
:concat
h; n
:loop
/^[[:space:]]/{
H; x; s/\n[[:space:]]*/ /; x; n;
/^[[:space:]]/b loop
}
x; p; x;
/^[A-Z]/b top
}
:next

解説

1 行目
:top

:で始まるのはラベル行です。

2 行目
/^$/q

ヘッダーにしか用はないので、ヘッダー部分が終了したら処理を打ち切ります。

3 行目 〜 17 行目

/^[A-Za-z]/{ ... }

ヘッダー行の先頭部分だったらこのブロックの中を実行します。

4 行目 〜 7 行目
/^[Ff][Rr][Oo][Mm]:/b concat
/^[Tt][Oo]:/b concat
/^[Cc][Cc]:/b concat
b next

From:, To:, Cc: のとき、:concat以降の結合処理にジャンプ(b concat)します。

そうでなければ、:nextのところにジャンプ(b next)します。

:next以降にコマンドはないので、sed は次の行の処理に移ることになります。

8 行目 〜 9 行目
:concat
h; n

現在の行をホールドスペースにコピーして(h)次の行を読み込みます(n)。

10 行目 〜 14 行目
:loop
/^[[:space:]]/{
H; x; s/\n[[:space:]]*/ /; x; n;
/^[[:space:]]/b loop
}

継続行を1行にまとめる処理です。

読み込んだ行が継続行であれば /^[[:space:]]/{ ... } のブロックの中が実行されます。

パターンスペースをホールドスペースに追加して(H)、改行と継続行先頭の空白を単一のスペースに置換します(s/\n[[:space:]]*/ /)。

xはパターンスペースとホールドスペースを入れ替えるコマンドです。sedの操作はパターンスペースに対してのみ実行可能なため、このように入れ替えを行います。

次の行を読み込んで(n)、さらに継続行であれば:loopのところにジャンプしてループを続けます(/^[[:space:]]/b loop)。

15 行目
x; p; x;

ホールドスペースには、1行にまとめられたヘッダー行が保存されているので、これを出力します。

16 行目
/^[A-Z]/b top

パターンスペースには次の行を読み込んであるため、ヘッダー行であれば先頭に戻って処理を続けます(/^[A-Z]/b top)。

注意

[[:space:]]

[:space:]はPOSIX正規表現で空白を示すメタ文字列です。文字セット([])の中でのみ効果を持つため、[[:space:]]のように書きます。

POSIX正規表現を理解しない、伝統的なsedでは [ スペース タブ ] といったように書きましょう。ただし、ターミナルに表示されているこの行を安易にコピー&ペーストすると、タブがスペースに展開されていたりしますので注意が必要です。

b コマンド

ラベルの後に ; で区切ってさらにコマンドを書くことができるのは GNU sed のみです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1