ファイルには様々な形式があります。1行単位で記述されたCSV(カンマ区切り)ファイルやTSV(タブ区切り)ファイルは、awkやsed、その他のbashコマンドなどを使っても比較的処理がしやすい。しかし、複数行でレコードが構成される場合(1行目が名前、2行目が住所、3行目が電話番号・・・など)は少し厄介です。awkで複数行のレコードを処理する方法を考えてみます。

awk レコードが複数行で構成される場合
レコード区切り(改行文字)・フィールド区切り(空白文字)の設定を任意の文字に変更することで、複数行にわたるデータを1レコード・1行毎のデータをレコード内のフィールドとして扱うことができます。
awk レコードは行単位がデフォルト
awkのデフォルトの処理単位は1行単位です。改行を目印に1行分1レコード読み取り、空白文字の区切り文字でフィールドに分割します。これらは、システム変数RS
・FS
で設定されています。
BEGEIN {FS="[ \t\n]+"; RS="\n"}
awk レコードの区切り文字を変更する
レコードが複数行で構成される場合、システム変数RS
を空白行(””)や任意の文字へ、システム変数FS
を改行(”\n”)へ変更します。これで、任意の区切り文字までの行ブロックが1つのレコードとなり、1行ずつの情報がレコード内のフィールドとして管理することができます。
BEGEIN {FS="\n"; RS=""}
awk 複数行の処理
awk 複数行を処理する(空白行が区切り)
システム変数RS
・FS
の設定を変更して、複数行でレコードが構成されるファイルを処理してみましょう。まずは、空白行が区切りの場合です。
awk lines1.dat
空白行が区切りとなるデータを準備します。
$ cat awk_lines1.dat name_1 address_1 tel_1 work_1 name_2 address_2 tel_2 work_2
awk lines1.awk
空白行を区切りとして、レコード処理します。各行がフィールドです。先頭と最後のフィールドを表示します。
BEGIN {FS="\n"; RS=""} {print $1, $NF}
実行と結果
$ awk -f awk_lines1.awk awk_lines1.dat name_1 work_1 name_2 work_2
awk 複数行を処理する(その他の文字が区切り)
システム変数RS
・FS
の設定を変更して、複数行でレコードが構成されるファイルを処理してみましょう。レコードの区切り文字が#(任意の文字)の場合です。
awk lines2.dat
#が区切りとなるデータを準備します。
$ cat awk_lines2.dat name_11 address_12 tel_13 work_14 # name_21 address_22 tel_23 work_24 #
awk lines2.awk
#を区切りとして、レコード処理します。各行がフィールドです。先頭と最後のフィールドを表示します。RS
を”#”としてもうまくいきませんでした。RSを”#\n*”と設定すると想定したとおりレコードを認識します。最後のフィールドはシステム変数NF
を使って$NFで表示できるかと思いましたが、(NF-1)番目と指定するとうまく表示できました。
BEGIN {FS="\n"; RS="#\n*"} {print $1, $(NF-1)}
実行と結果
$ awk -f awk_lines2.awk awk_lines2.dat name_11 work_14 name_21 work_24
実験データの解析や論文用グラフ作成のヒントになりそうな、プログラミング・統計処理の参考になる書籍をまとめて紹介しています。是非、参考にしてみて下さいね。

関連記事













