2012年10月28日日曜日

#hbstudyハンズオン


10問お題が出されてそれをbashワンライナーで解けという内容でした。
普段からのコマンド習熟度が問われるわけですね。
・・・と思ったらawk習熟度が思いっきり問われました。

以下は自分が知らなかったことの(断片的な)まとめ。

標準入力をcatで受け取るには


ハイフンを引数に取ればいける。知らなかった。
もちろん複数の引数をとればcatの出力は連結される。

$ echo "hoge" | cat -


bashでデータをランダムにシャッフルするには

慣れている人がやればawkでもうこれは慣用句らしい。

以下は1~10の数字をランダムにシャッフルする例


$ seq 1 10 | awk '{print rand()" "$1}' | sort | awk '{print $2}'
10
4
8
6
1
2
9
5
7
3
awkでの切った貼ったはお手のものですね。

欠けているデータを探すには

お題では1~10までのどれか一つの数字が欠けていてさらにシャッフルされたデータがあるとき、その欠けている数字のみを表示するというもの。
diffはそれ以外のものも表示されてしまうので禁止。


$ cat num
10
8
6
1
2
9
5
7
3
$ seq 1 10 | cat - num | sort -n | uniq -u
4

ここの問題のミソは比較したいデータをまとめてソートしてuniqで一行しかないものをとってくると言うこと。-uオプションとかこういう風に使えるのね。

FizzBuzz問題

できるだけエレガント?に

$ seq 1 100 | awk '$1%15==0{printf "FizzBuzz "} $1%5==0{printf "Buzz "} $1%3==0{printf "Fizz "} {print $1" "}' | awk '{print $1}' | tr "\n" " "

1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buz

まあこれはいろんな方法がありそう。自分は最初bashのtestコマンドで頑張っていたがawkの方が短くなるね。


所感?

印象深かったことは、玄人(バイニン)の人たちは息をするかの如くawkを書きなぐっていたこと。
自分はawkほとんど慣れていなかったので、後半はついていけなかった。。

あの時間から3時間シェルと遊ぶのはなかなかエネルギーが必要やったけど、いい勉強になった。

2012年10月14日日曜日

MongoDBメモ

MongoDBのインポートコマンドのメモ
mongoimport -v -d Document名 -c Collection名 --file JSONファイル
上記のコマンドで、JSONファイルで書かれたデータをMongoDBにインポートできる。

2012年10月2日火曜日

Scala体験記_2

Scalaのifは文(statement)じゃ無くて式(expression)なんだぜ。だから以下のように書けたりする。

    val a = if (1 < 2 ) {10} else {20}
    println(a)
まぁこれだけやと三項演算子と何が違うの?っていわれそうやけども。

if式でハマってしまったのは、if式の評価順が予想よりも低いこと。
以下の例の出力結果はどうなるやろうか。


    val a = if (1 < 2 ) {
       10
    } else {
       20
    } 
       + 5
    println(a)

意味もなくネストして書いてみたけど、こいつの出力結果は10となる。 これはifよりも{20} + 5が先に評価されたせい。 これに気づかずに1時間ぐらい悩んでたら良くある誤解として取り上げられていたのでメモ。

2012年10月1日月曜日

Scala体験記


Scalaを使って何か書いてみようと思ったけど、基本的なループの書き方すらよく分かってなかったので復習がてら内容をメモ

以下Int型リストの総和を求めるというものすごく簡単な例

関数型っぽく書いたとき


def calcsum(list:List[Int]) : Int = {
    if (list.isEmpty)
      0
    else
      list.head + calcsum(list.tail)
  }

Java(手続き型)っぽく書いたとき


  def calcsum2(list:List[Int]) : Int = {
    var sum = 0
    for( value <- list) sum += value
    sum
  }

こういう風に関数型と手続き型の両方で書けるのがScalaのいいところ。 その気になれば全部Javaっぽく書くのも可能。