awkガナス

第6回 複数ファイルへの出力(リダイレクト機能)

2015.09.02

今回はリダイレクト機能について書きます。

awkはリダイレクト機能があるので複数ファイルへの出力ができます。print文の後にファイル名を書くことで出力をファイルにリダイレクトできます。

% ls -l | awk '{print > "aa"}'
  • > 新規作成
  • >> 既存のファイルへ追加
% ls -l | awk '{print >  "aa"}' # 新規作成
% ls -l | awk '{print >> "aa"}' # 既存のファイルへ追加

ファイル名はダブルコートで囲む。ダブルコートで囲まないと変数として解釈される。

% ls -l | awk '{aa="out.txt"; print > aa}'

上記の場合、out.txt というファイルに出力される。

patternと組み合わせてファイル出力

patternと組み合わせることによってファイルの振り分けが簡単にできます。

以下は、ls -l の出力が以下の条件の時の振り分けの例。

  • ファイルの時刻情報に ‘:’ があった時は this.year に出力する
  • ファイルの時刻情報に ‘:’ なかった時は old.year に出力する
$8  ~ /:/ { print> "this.year" }
$8 !~ /:/ { print>  "old.year" }

10行ごとにファイル出力

出力ファイル名を変数に定義して10行ごとにファイル出力する例。

% awk '{
    if( NR%10 == 1 ){
              close(out) # 直前まで出力していたファイル
              out = sprintf("aa%03d", NR/10)
        }
        print > out  # 変数out に定義したファイル名に出力
  }' file

以下のファイル名でファイルが作成される。

% ls aa*
aa000 aa001 aa002 aa003 aa004

時間毎にファイル出力

% awk -F: ' {           # 区切りを ':' にする
    close(out)          # ファイルオープンの数に限りがあるので都度close
    out = $1            # $1 == Apy 16 10
    gsub(/ /, "_", out) #スペースをアンダーバーに置き換え
    print >> out
}' /var/log/syslog

% ls -l Apr*
-rw-r--r-- 1 naka member 843  4月 16 16:59 Apr_16_10
-rw-r--r-- 1 naka member 393  4月 16 16:59 Apr_16_11

diffの出力を分割

% git diff | awk '/^diff/ {
        close(out);
        out = sprintf("out%02d",n++)
    }
    { print > out }'

% ls
out00 out01 out02 out03 out04 out05

エラー出力を行う

エラー出力をしたい場合は /dev/stderrにリダイレクト。

ls -l | awk '{print >"/dev/stderr"}'

標準出力は /dev/stdoutにリダイレクトもできます。

ls -l | awk '{print >"/dev/stdout"}'

パイプ

print の後ろには | パイプもかけます。

awk '{print|"sort"}'
awk '{print|"sed s/2013/XX13/"}'

パイプした後、ファイルにリダイレクトもできる。

awk '{print|"sort > sort.out"}'
awk '{print|"sed s/2013/XX13/ > sed.out"}'

パイプは複数実行できる。sedした後、grep してリダイレクトの例。

awk '{print|"sed s/2013/XX13/|grep XX> grep.out"}'

リダイレクトでsort

リダイレクト”sort” を指定した場合、awk の後に sort した場合と同じ結果になる。

% ls -l | awk '{print $8|"sort"}'

09:46
14:38
15:13
15:39
% ls -l | awk '{print $8}' | sort
09:46
14:38
15:13
15:39

パイプの中でawkコマンドを実行

print の後にパイプで整形するawkを実行することもできますので以下のようにかけます。

% awk -F: '{print $1,$2|"uniq -c|awk -f pr.awk"}'

    Sep 24 23:58 - count:16
    Sep 25 00:47 - count:24
    Sep 25 00:56 - count:16
pr.awkの内容:
{printf("%s %s %s:%s - count:%2d\n",$2,$3,$4,$5,$1)}

著者プロフィール

naka

すきなコマンドは awk と bc です。なにかを計算する時、awk か bc を使います。

記事一覧Index