For instance, here's a Ruby one-liner that uppercases the input:
% echo matz | ruby -p -e '$_.tr! "a-z", "A-Z"'
MATZ
You like that kind of stuff? Yes? Excellent! Then I offer you a hacking idea for Scala.
As you may know, Scala offers similar capability with the -e command-line option but it's fairly limited in its basic form because of the necessary boilerplate code to set up iteration over the standard input... it just begs for a simple HACK!
Using a simple bash wrapper,
#!/bin/bash
#
# Usage: scala-map MAP_CODE
#
code=$(cat
scala.io.Source.stdin.getLines map { $@ } foreach println
END
)
scala -e "$code"
then we can express similar one-liners using Scala code and the standard library:
% ls | scala-map _.toUpperCase
FOO
BAR
BAZ
...
% echo "foo bar baz" | scala-map '_.split(" ").mkString("-")'
foo-bar-baz
Nifty, right? Here's another script template to fold over the standard input,
#!/bin/bash
#
# Usage: scala-fold INITIAL_VALUE FOLD_CODE
#
# where the following val's can be used in FOLD_CODE:
#
# `acc` is bound to the accumulator value
# `line` is bound to the current line
#
code=$(cat <
println(scala.io.Source.stdin.getLines.foldLeft($1) { case (acc, line) => $2 })
END
)
scala -e "$code"
Now if you wanted to calculate the sum of the second column of space-separated input, you'd write:
$ cat | scala-fold 0 'acc + (line.split(" ")(1).toInt)'
foo 1
bar 2
baz 3
(CTRL-D)
(CTRL-D)
6
You get the idea ... hopefully this inspires you to try a few things with Scala scripting templates!
Disclaimer: I am not advocating these hacks as replacement to learning other Unix power tools like grep, sed, awk, ... I am simply illustrating that Scala can be turned into an effective command-line scripting tool as part of the vast array of Unix tools. Use what works best for you.
Disclaimer: I am not advocating these hacks as replacement to learning other Unix power tools like grep, sed, awk, ... I am simply illustrating that Scala can be turned into an effective command-line scripting tool as part of the vast array of Unix tools. Use what works best for you.
2 comments:
I needed to change the first example to:
code=$(cat <<EOF
scala.io.Source.stdin.getLines map { $@ } foreach println
EOF
)
scala -e "$code"
to make it work. Otherwise, great blog post and great tricks :)
Grega
Hi! I needed to change the bash code a bit to make the first example work:
code=$(cat <<EOF
scala.io.Source.stdin.getLines map { $@ } foreach println
EOF
)
scala -e "$code"
Great tricks, really liked the post!
Post a Comment