awk if サンプルでわかる条件文の書き方 一致・大小比較・正規表現を簡潔に書く方法

awkのif条件文は、条件によって処理をわけたいときに使います。条件式では、0の判定・関係演算子・パターンマッチなどを判定します。省略記法や条件演算子を使うことで、awkのif文を簡潔に書くことができます。

awk if 条件で処理を分ける

awkのifでは、条件式に対して「条件を満たす場合に実行する処理」「満たさない場合に実行する処理」をそれぞれ分けて書きます。複数の条件を続けて書く場合は、if, else if, elseなどを組み合わせて書きます。

書式

awkの条件文は、if キーワードの直後にカッコ()でくくられた条件式を書き、続けて「条件を満たしたときに実行する処理」を書きます。実行する処理が複数行に渡る場合は、中括弧{}で囲みます。もし、「条件を満たさないときに実行する処理」が必要な場合は、else キーワードの後に書きます。もし、更に条件を細かく追加する場合は、if と else の間に else if で条件を書きます。

1: if ( expression )
2:   action1
3: else if ( expression )
4:   action2
5: else
6:   action3

awk if 条件をいくつかに分ける

if, else if, elseを使って、より細かく分岐処理を分けることができます。else や else if はオプションなので、必要な場合のみ追加します。

if – 単純な分岐

awkのif文を使って、ファイル内に空白行があるかを調べています。ifで指定した条件は、「if ($1 ~ ^$)」です。空白行が存在した場合に「blank line」と表示しています。NRを使って、該当する行番号も一緒に表示しています。

 1: # テストファイル
 2: $ cat > test.txt << EOF
 3: a
 4: b
 5: 
 6: c
 7: EOF
 8: 
 9: # awk if
10: $ cat test.txt | awk '{if ($1 ~ /^$/) print "blank line", NR}'
11: blank line

else – 条件に合うとき・条件に合わないとき

awkのif文を使って、ファイル内に空白行があるかを調べています。ifで指定した条件は、「if ($1 ~ ^$)」で、空白行でない場合の動作は「else」で指定しました。空白行が存在した場合に「blank line」と表示しています。そうでない場合は、行全体を print で表示しています。

1: $ cat > test.txt << EOF
2: a
3: b
4: 
5: c
6: EOF
7: $ cat test.txt | awk '{if ($1 ~ /^$/) print "blank line"; else print}'

else if – 条件を加える

awkのif文を使って、ファイル内に空白行・コメント行があるかを調べています。ifで指定した空白行の条件は「if ($1 ~ ^$)」で、コメント行の条件は「else if ($1 ~ ^#)」、どちらでもない場合の動作は「else」で指定しました。空白行では「blank」、コメント行では「comment」と表示しています。そうでない場合は、行全体を print で表示しています。

 1: $ cat > test.txt << EOF
 2: a
 3: b
 4: #
 5: 
 6: c
 7: EOF
 8: 
 9: $ cat test.txt | awk '{if ($1 ~ /^$/) print "blank"; else if ($1 ~ /^#/) print "comment"; else print}'
10: a
11: b
12: comment
13: blank
14: d

awk if 式の評価でチェックできること

数字の0(ゼロ)は「偽」、空の文字列も「偽」となります。式の評価には、大小比較を行う関係演算子や文字列のパターンを調べる正規表現などが利用できます。

ゼロ・存在するかどうか?

awkのif文で、引数をチェックします。引数が「0」と「空文字」のときは、偽で評価されるので引数は表示されません。

1: $ awk 'BEGIN {if (ARGV[1]) print ARGV[1]}' 1
2: 1
3: 
4: $ awk 'BEGIN {if (ARGV[1]) print ARGV[1]}' 0
5: (表示なし)
6: 
7: $ awk 'BEGIN {if (ARGV[1]) print ARGV[1]}'
8: (表示なし)

関係演算子で大小比較や一致を調べる

awkのif文で、大小比較をします。行番号を引数で渡して、指定より大きな行番号の行だけ表示します。ifで指定した比較の条件は「if (NR > line)」で、現在の行番号と指定した行番号を比較しています。引数で2を指定したので、ファイルの3行目・4行目だけ表示されます。

 1: $ cat > test.txt << EOF
 2: a
 3: b
 4: c
 5: d
 6: EOF
 7: 
 8: $ cat test.txt | awk -v line=2 '{if (NR > line) print}'
 9: c
10: d

awkのif文で、一致をチェックします。行番号を引数で渡して、指定した行番号の行だけ表示します。ifで指定した比較の条件は「if (NR == line)」で、現在の行番号と指定した行番号を比較しています。引数で2を指定したので、ファイルの2行目だけ表示されます。

1: $ cat > test.txt << EOF
2: a
3: b
4: c
5: d
6: EOF
7: 
8: $ cat test.txt | awk -v line=2 '{if (NR == line) print}'
9: b

文字列のパターンを調べる

awkのif文で、正規表現を使ってパターンマッチをチェックします。以下のような条件を指定することができます。

  • 先頭がa : if ($1 ~ ^a)
  • 末尾がd : if ($1 ~ d$)
  • 先頭がa または b : if ($1 ~ ^[ab])
  • 先頭がa または b の否定 : if ($1 ~ [^ab])
 1: $ cat > test.txt << EOF
 2: a
 3: b
 4: c
 5: d
 6: EOF
 7: 
 8: $ cat test.txt | awk '{if ($1 ~ /^a/) print}'
 9: a
10: 
11: $ cat test.txt | awk '{if ($1 ~ /d$/) print}'
12: d
13: 
14: $ cat test.txt | awk '{if ($1 ~ /^[ab]/) print}'
15: a
16: b
17: 
18: $ cat test.txt | awk '{if ($1 ~ /[^ab]/) print}'
19: c
20: d

awk if 短く簡潔に書く方法

if 改行を省略して簡潔に短く書く

単純なif文は、改行を省略して、セミコロン(;)で処理を区切って書くと簡潔に書けます。awkのスクリプトファイルとして保存した、長いスクリプトと短いスクリプトを比較しました。どちらも結果は同じです。ただし、ifやelse後の処理が複数行になる場合は、中括弧を省略できません。

 1: $ cat > test.txt << EOF
 2: a
 3: b
 4: 
 5: c
 6: EOF
 7: 
 8: # 中括弧{} をきちんと使ってかいた場合(長い)
 9: $ cat my_awk
10: {
11:   if ($1 ~ /^$/) {
12:     print "blank"
13:   }
14:   else {
15:     print
16:   }
17: }
18: 
19: $ cat test.txt | awk -f my_awk
20: a
21: b
22: blank
23: c
24: 
25: # 中括弧{} を省略して書いた場合(短い)
26: $ cat my_awk2
27: {
28:   if ($1 ~ /^$/) print "blank"; else print
29: }
30: 
31: $ cat test.txt | awk -f my_awk2
32: a
33: b
34: blank
35: c

単純な分岐を条件演算子で書く

単純なif文は、条件演算子で書くと更に簡潔に書けます。判断部分は「($1 ~ ^$) ? action1 : action2」で、「?」の前の条件式を満たせば「action1」を実行し、条件式を満たさなければ「action2」を実行します。条件を満たしたときは変数infoに”blank”を代入し、満たさないときは$0(行全体)を代入しました。どちらの場合もprintでinfoの内容を表示しています。

 1: $ cat > test.txt << EOF
 2: a
 3: b
 4: 
 5: c
 6: EOF
 7: 
 8: # 条件演算子を使ってかいた場合(短い)
 9: $ cat my_awk3
10: {
11:   print info = ($1 ~ /^$/) ? "blank" : $0
12: }
13: 
14: $ cat test.txt | awk -f my_awk3
15: a
16: b
17: blank
18: c

まとめ

  • awkのif条件文は、条件によって処理をわけたいときに使う。
  • 条件式は、0の判定・関係演算子・パターンマッチなどを使って書く。
  • 省略記法や条件演算子を使えば、awkのif文をより簡潔に書ける。

実験データの解析や論文用グラフ作成のヒントになりそうな、プログラミング・統計処理の参考になる書籍をまとめて紹介しています。是非、参考にしてみて下さいね。



ピックアップ記事

  1. awk split サンプルでわかる列の分割とセパレータ(文字・正規表現)の指定方法

    awkのsplit関数は、セパレータを指定して文字列を分割することができます。セパレータには文字や…
  2. awk for 繰り返し処理 簡単なサンプルでわかる インクリメント・デクリメント、変わった繰り返し

    awkのfor文は、カウンタを目印にして処理を繰り返したいときによく使われます。for文では、カウ…
  3. tidyverse – distinct関数でデータフレームの重複行を削除 dplyrパッケージ

    tidyverseでデータフレームの重複行の削除を行う場合、dplyrパッケージのdistinct…

人気記事

  1. IGV, 解析ツール

    IGV 使い方 インストール〜便利な使い方まで | リファレンス・マッピングデータ・アノテーションを読み込んで表示しよう
    IGV(Integrative Genomics View…
  2. Excel, その他, 統計

    z-score 計算方法 エクセル(Excel) 編
    統計処理で、大きく変化しているなどの判断基準にも使われる値…
  3. R データ型 - 文字列・ベクター・データフレーム・マトリックス など-, R言語, スクリプト

    R subset関数 データフレームやmatrixからの条件指定による行・列の抽出
    R の subset関数は、データフレームやマトリックスか…

おすすめ記事

  1. bash 応用, シェルスクリプト

    シェル スクリプト ファイル存在チェック・空のファイルチェック
    bashでスクリプトを作成するときに、よく使うのがファイル…
  2. awk, bash 文字列操作, シェルスクリプト

    bash 部分文字列・置換・長さ・連結・分割の文字列処理
    bashのよく使う文字列処理、部分文字列・置換・連結・長さ…
  3. R言語, グラフ

    R 使い方 軸・ラベルの調整(向き・サイズ・色など) グラフの描き方
    Rによるplot(グラフ)の描画は、手軽で大変便利です。た…