0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

gawk で strtonum を使うときの注意

0
Posted at

gawk で strtonum を使うときの注意

たまに csv を処理するのに csv オプションのために gawk を使っているんですが、ちょっと困惑したことがあったので覚書として残しておきます。

はじめに

test.csv
NAME,SCORE
Adam,0x11
Brian,100
Charlie,0
David,Emmie

このようなファイルからヘッダーと SCORE が数字以外になっている行を除いたものがほしいとする。

単純に、

$2 ~ /^[0-9]+$/ {print $0}
# Brian,100
# Charlie,0

というのが第一に思いつくところではないか。

しかし、負の数や 16 進数があるとうまくいかない。

ここで思いつくのが strtonum だ。gawk 拡張だが、前述の通りここでは gawk を前提とする。

strtonum

strtonum は読んで字のごとく文字列を数字にしてくれる便利関数である。

これを私は次のように使ったことがある(この記事はそのときに調べたことの要約である)

# post.txt は上記の test.csv とはなんの関係もない。
sed -n '2,$p' posts.txt | \
gawk --csv 'strtonum($3) {print $0}' | 
sort -k 3 -t , -n  | \
# 以下略

このスクリプトの気の利いていない点は sed が不要なこともあるが、 $3 が 0 のときも無視されてしまうことが問題だ。

具体的は下のコードのようになる。

{
    if (strtonum($2)) {
        print $1,strtonum($2)
    } else {
        print $1,$2, ": An error occurred."
    }
}
# NAME SCORE : An error occurred.
# Adam 17
# Brian 100
# Charlie 0 : An error occurred.
# David Emmie : An error occurred.

これは awk では 0 を偽として扱うということであるから、次のようにする。

$ cat test.csv  | gawk --csv '(strtonum($2) || $2 == "0") {print $1,strtonum($2)} '
# Adam 17
# Brian 100
# Charlie 0

他の awk で strtonum を使いたい場合は Link から GNU Awk のマニュアルにコードがあるのでそちらを参照されたい。

おわりに

結局の所 awk では 0 は falsy であるということだ。
falsy のポリシーは言語ごとに異なっているため気をつけよう。

Link

The GNU Awk User’s Guide

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?