Line Filters in Clojure
A line filter is a common type of program that reads input on stdin, processes it, and then prints some derived result to stdout. grep and sed are common line filters.
Here’s an example line filter in Clojure that writes a capitalized version of all input text. You can use this pattern to write your own Clojure line filters.
(ns line-filters.core
(:require [clojure.string :as str])
(:gen-class))
(defn -main [& args]
(doseq [line (line-seq (java.io.BufferedReader. *in*))]
(println (str/upper-case line)))
(flush))Let’s break down this code:
We define a namespace and require the
clojure.stringlibrary for string manipulation.The
-mainfunction is the entry point of our program.We use
line-seqwithjava.io.BufferedReader.to create a lazy sequence of lines from standard input.We iterate over each line using
doseq.For each line, we use
str/upper-caseto convert it to uppercase andprintlnto print it.Finally, we
flushthe output to ensure all data is written.
To try out our line filter, first make a file with a few lowercase lines.
$ echo 'hello' > /tmp/lines
$ echo 'filter' >> /tmp/linesThen use the line filter to get uppercase lines.
$ cat /tmp/lines | lein run
HELLO
FILTERNote: To run this Clojure script, you need to have Leiningen installed and set up a project. Alternatively, you can use clj with the appropriate classpath set up.
This Clojure version accomplishes the same task as the original example, reading lines from standard input, converting them to uppercase, and printing the result. The main differences are:
- Clojure uses
line-seqinstead of a scanner to read lines. - String manipulation is done using the
clojure.stringlibrary. - Error handling is implicit; Clojure will throw exceptions if there are I/O errors.
Remember to handle potential exceptions in a production environment.