Just another Ruby porter,


9月下旬の日記 | RDF

2014-09-30 (Tue)

awkの配列の長さ

AWKのトリッキーな配列&連想配列の仕組み・動作と目からウロコのテクニック (1/2):CodeZineで、

このlength関数は少し特殊で、引数がない場合には$0の文字数を返し、引数が変数の場合には変数の長さを返します。 引数が配列である場合には、配列の個数を返します。 このようにlength関数はちょっとトリッキーな関数です。 一部のAWKではバグが残っていて、うまく動作しないこともあります。

のように書かれているが、これはバグではなくて一部のawkの拡張機能。
もともとlengthは文字列しか受け付けない。 POSIXでもlength(配列)は規定されていない。

そのあたりの違いは AwkChannelWiki: Awk Feature Comparisonが詳しい。

% gawk 'BEGIN{split("foo bar", a);print length(a)}' 
2
% bwk 'BEGIN{split("foo bar", a);print length(a)}'
2
% gawk --posix 'BEGIN{split("foo bar", a);print length(a)}'
gawk: コマンドライン:1: 致命的: length: 配列引数を受け取りました
% mawk 'BEGIN{split("foo bar", a);print length(a)}' 
mawk: line 1: illegal reference to array a
% busybox awk 'BEGIN{split("foo bar", a);print length(a)}'
0

2014-09-29 (Mon)

9月の10分置きの気温を気象庁から取ってくる

気象庁|過去の気象データ検索から知りたい地点やらもろもろ選ぶ。
dayは01のように0をつけても受け付けてくれるようだ。
awkならFSとRSを適当に設定すれば結構簡単に抜き出せる。

for i in {01..28};do
  curl -s "http://www.data.jma.go.jp/obd/stats/etrn/view/10min_a1.php?prec_no=43&block_no=0363&year=2014&month=9&day=$i&view=" | \
  awk '/data_0_0/{print date, $1, $3}' date=2014-09-$i FS='</td><td[^>]*>' RS='nowrap">|</td></tr>\n'
done | tee saitamashi-201409.log

これを例のあれで日ごとの最低気温を出すとこうなる。

% sort -k1,1 -k3,3n saitamashi-201409.log | awk '!a[$1]++'
2014-09-01 18:20 20.0
2014-09-02 05:00 18.6
2014-09-03 05:40 21.2
2014-09-04 05:00 21.5
2014-09-05 05:20 21.5
2014-09-06 21:30 23.0
2014-09-07 08:50 18.4
2014-09-08 05:00 17.0
2014-09-09 05:00 18.9
2014-09-10 06:00 20.0
2014-09-11 23:40 18.3
2014-09-12 06:00 17.0
2014-09-13 04:50 17.2
2014-09-14 05:10 17.3
2014-09-15 02:10 18.9
2014-09-16 06:00 19.3
2014-09-17 23:50 20.0
2014-09-18 23:30 17.7
2014-09-19 04:30 13.4
2014-09-20 24:00 14.4
2014-09-21 05:40 11.8
2014-09-22 04:00 16.4
2014-09-23 04:20 14.1
2014-09-24 05:50 15.2
2014-09-25 03:40 21.0
2014-09-26 23:40 19.3
2014-09-27 05:50 15.7
2014-09-28 02:50 14.2

実際の値とはちょっと違うが、10分よりももっと細かい間隔でも測定してると思われる。


2014-09-28 (Sun)

新bash

すでにUbuntuでは最新のpatchがあたったバージョンのbashが使えるが、どのように修正されたのか。
いろいろ調べてみると環境変数でimportする機能は生き残っていた。
さすがに任意の名前はまずいのでBASH_FUNC_とprefixがつくようになった。
さらにsuffixとして関数らしく()もつく。
つまりxという関数だったらBASH_FUNC_x()となる。
この名前の環境変数で中身が"() { }"という形式になっていればimportされる。

% env 'BASH_FUNC_x()=() { echo hello;}' bash -c x
hello

envなしでは無理。bashでもdashでもkshでもzshでも名前に()を含む環境変数は作れない。

あと例の警告もちゃんとまだ活きている。

% env 'BASH_FUNC_x()=() { :;};date' bash -c x
bash: 警告: x: ignoring function definition attempt
bash: `BASH_FUNC_x' の関数定義をインポート中にエラーが発生しました
bash: x: コマンドが見つかりません

curlでヘッダに設定してもHTTP_がつくしhttpdによっては()が_に変換されたりするのでやはり無理っぽい。

% curl -sH 'BASH_FUNC_x(): () { :;}; date' http://localhost/cgi-bin/env.cgi | grep BASH_FUNC
HTTP_BASH_FUNC_X__=() { :;}; date

2014-09-27 (Sat)

連番機能

qiitaに bashのインストール方法が書いてあった。
それはまあいいとして、面白いのはfor文で {000..25} とはせずに
$(seq -f "%03g" 0 25) と書いてあること。
これはここではbashを使ってないということをアピールしているのだろうか。

それはそれとして実はwgetじゃなくてcurlを使えば簡単に連番処理できる。

% curl -O 'http://ftp.gnu.org/gnu/bash/bash-4.3-patches/bash43-[000-025]'

man curlすると一番最初に書いてあるから、きっとある方面では一番需要がある機能なんだろう。


2014-09-26 (Fri)

nasne 2.5

リモート視聴とかFLACとかはどうでもいいが、DLNAアップロード機能が気になった。
Smart J:COM Boxからnanseへ保存できれば全部nasneで操作できるわけで。
まあ、そんな都合のいいことはできなかったが、
逆にnasneに保存されてる番組はSmart J:COM Boxで見られるようにはなった。
ひょっとしたら前からできてたかもしれないが、全然うれしくない。


9月下旬の日記 | RDF


WWW を検索 jarp.does.notwork.org を検索

わたなべひろふみ
Key fingerprint = C456 1350 085F A320 C6C8 8A36 0F15 9B2E EB12 3885
Valid HTML 4.01!