テキストのパターンマッチ処理に長けたスクリプト言語

awk

awk はテキストのパターンマッチ処理に長けたスクリプト言語である。Perl や Python ほどの機能を持たないが、Linux のコマンドのように使えて、ほんの数行だけで強力なテキストパターンマッチングを発揮できる。

awk を利用したパターンマッチング

awk は、あるパターンにマッチングした時に、それに応じた処理を行うコマンドである。例えば、sample.tsv ファイル中に abc を含む行があれば、それを画面上に出力する場合は以下のようにする。/abc/ のようにパターンを指定し、{print $0} で処理を行う。この場合、$0 を画面上に出力する処理を行っている。$0 は、awk でファイルの 1 行文の内容を表すと定義されている。。

awk '/abc/{print $0}' sample.tsv

タブ区切りのテキストファイル sample.tsv の第 1 列と第 3 列の内容を出力する場合は次のようにする。まず、メインの処理を実行する前に、BEGIN ブロックが処理されて、区切り文字 FS としてタブを \t をセットアップする。次に、print 関数を利用して、ファイルをタブ区切りとみなしたときの、第 1 列と第 3 列を出力する。この場合は、すべての行に対して処理を行うので、パターンを省略する。

awk 'BEGIN{FS="\t"}{print $1, $3}' sample.tsv

awk で 2 列目の数値と 3 列目の数値の和を計算して出力する場合は、次のようにする。

awk '{print $2 + $3}' sample.tsv

各行の内容の前に行番号を追加する場合は次のようにする。

awk '{print NR, $0}' sample.tsv

ファイル中の偶数行だけを出力したい場合は次のようにする。

awk 'NR % 2 == 0 {print $0}' sample.tsv

awk 組み込み変数

awk にはいくつかの組み込み変数が存在する。例えば、現在の処理しているファイルの行数や列数などの情報が組み込み変数に保存されている。

組み込み変数機能
$0ファイル1行(レコード)分の内容。
$n現在の行の、n 番目のカラム(フィールド)のテキスト内容。
RSフィールドの区切り文字。デフォルトは改行文字。
FS1 行のテキストをカラムに分割する際に利用する区切り文字。
OFSFS と同じく区切り文字を表します。OFS は処理結果を出力するときの区切り文字として利用される。
NF現在のカラム数(区切り文字で区切った時にできる列数)
NR現在の行数

awk の応用例

CSV ファイルはカンマで規則正しく区切られたファイルであり、awk を利用して簡単にデータを抽出したり、加工したりすることができる。

data.csv を読み込んで、各列の平均を出力する場合は次のようにする。

awk '
  BEGIN{
    FS = ","
  }
  {
    for (i = 1; i <= NF; i++) {
      s[i] += $i
    }
  }
  END{
    for (i = 1; i <= NF; i++) {
      print s[i] / NR
    }
  }' data.csv

各列の絶対値を出力する場合は次のようする。

awk '
   BEGIN{
      FS = ","
   }
   {
      for(i = 1; i <= NF; i++){
         ($i < 0) ? $i = -$i : $i = $i
      }
      print $0
   }
' data.csv

1 列目のデータを、小数 4 桁で表示する例。

awk 'BEGIN{FS=","}{printf("%.4f\n",$1)}' data.csv

FASTA を FASTQ ファイルに変換する場合は、各エントリーに対して、次のように第 1 行と第 2 行を出力してから、第一行目の先頭にある @ を > に変換すればよい。

awk 'NR % 4 == 1 || NR % 4 == 2' SRR000001.fq | sed -e 's/^@/\>/' > SRR000001.fa

awk で利用できる正規表現

awk(gawk v3.0)で利用できる正規表現。

grepsedawk
...
***
^^^
$$$
¥( ¥)¥( ¥)( )
\1 \2 \3\1 \2 \3\1 \2 \3
[ ][ ][ ]
¥{n, m¥}¥{n, m¥}{n, m}
¥{n, ¥}¥{n, ¥}{n, }
¥{n¥}¥{n¥}{n}
\+\++
\??
\|\||