awk 演習:タグ値ペアを扱う ― 2009年03月13日 09時25分23秒
文字をエスケープするのを避ける為に、書式には柔軟性を持たせる。区切り文字は文字列の最初の文字を用いる。タグには空白以外の任意の文字を使える。タグの後に空白一つが入り、それ移行は区切り文字までが、全て値とする。
例をあげると、|product book|price 1000|pages 135|paper_size B5|
等として、本の属性を表せる。
この形だと、実用上ではエスケープ文字などを作らないでの運用が可能になり、二文字を用いて一文字を洗わす処理が回避できる。例えば、\n
を用いて ASCII の改行を示すのは、よくプログラム言語で使われる。
これらの値を一括変換したり、一部だけ抽出するのに awk が使える。
% cat tag-value.awk
{ # break each component of tag-value into a hash table
FS = substr($0, 1, 1)
for(i in pairs) delete pairs[i]
for(i = 1; i <= NF; i++)
{
tvsplit($i)
pairs[key] = value
}
}
{
print tvmsg(pairs)
}
function tvsplit(word){
key = substr(word, 1, index(word, " ") - 1)
value = substr(word, 1 + index(word, " "))
}
function tvmsg(attr){
msg = sprintf("%s", FS)
for(i in attr)
if(attr[i] != "")
msg = msg sprintf("%s %s%s", i, attr[i], FS)
return msg;
}
この例では、一度分解した後に再構築しているだけなので、希望の処理を適時いれる。awk ではライブラリを作りづらいのが難点だ。gawk 等、複数のプログラムを指定できるなど拡張されている場合もあるが、古い処理系だとそれも出来ない。awk は書き捨てと潔く諦め、必要最低限に留めている。
例えば、全ての値段を 10% 上げる場合は、pairs["price"] = pairs["price"] * 1.1
等として使う。
最近のコメント