Skip to content

Instantly share code, notes, and snippets.

@tototoshi
Created August 15, 2012 03:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tototoshi/3355439 to your computer and use it in GitHub Desktop.
Save tototoshi/3355439 to your computer and use it in GitHub Desktop.
scala で awk っぽいの
package sawk
import scala.io.Source
import scala.collection.mutable.Map
object Sawk {
def apply(script: SawkScript): Unit = {
script.run
}
}
abstract class SawkScript(lines: Iterator[String], val FS: String = "\t") {
private var _main: (String, List[String]) => Unit = (x, xs) => ()
private var _begin: () => Unit = () => ()
private var _end: () => Unit = () => ()
def BEGIN(f: => Unit): Unit = {
_begin = () => f
}
def MAIN(f: (String, List[String]) => Unit): Unit = {
_main = f
}
def run(): Unit = {
_begin.apply
lines.foreach { l =>
val line = l
val fields = l.split(FS).toList
_main.apply(line, fields)
}
_end.apply
}
def END(f: => Unit): Unit = {
_end = () => f
}
}
// awk スクリプト
class CountUpScript(lines: Iterator[String]) extends SawkScript(lines) {
var data: Map[String, Int] = Map.empty.withDefaultValue(0)
BEGIN {
println("合計を計算します")
}
// line: 現在行
// line: 現在行をFSで分割したフィールド
MAIN { (line, fields) =>
data(fields(0)) += fields(1).toInt
}
END {
data.map { case (k, v) => k + "\t" + v }.foreach(println)
}
}
object Main {
def main(args: Array[String]): Unit = {
val data="""|りんご 1
|りんご 3
|みかん 2
|りんご 4
|みかん 5
|なし 3
|""".stripMargin
val awkScript = new CountUpScript(data.lines)
Sawk(awkScript)
/*
Output:
合計を計算します
なし 3
みかん 7
りんご 8
*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment