views:

135

answers:

2

Hi!

I am trying to get Clojure to read a file, put the first line in a variable, and the rest in another variable. I cannot seem to find out how to do this and would love if anyone could give me a heads up,

+4  A: 
;; for Clojure 1.1
(require '[clojure.contrib.duck-streams :as io])
;; for bleeding edge
(require '[clojure.java.io :as io])

(with-open [fr (io/reader "/path/to/the/file")]
  (let [[first-line & other-lines] (doall (line-seq fr))]
    ;; do stuff with the lines below...
    ...))

Update: Ah, just realised that I took "the rest" from the question to mean "the rest of the lines in the file", thus in the above other-lines is a seq of all the lines in the file except the first one.

If you need "a string containing the rest of the file's contents" instead, you could use the above code, but then (require '[clojure.contrib.str-utils2 :as str]) / (require '[clojure.string :as str]) (depending on the version of Clojure you're using) and say (str/join "\n" other-lines) to rejoin other-lines into one string; or, alternatively, use something like this:

(let [contents (slurp "/path/to/the/file")
      [first-line rest-of-file] (.split #"\n" contents 2)]
  ...)
Michał Marczyk
+2  A: 

Clojure head:

(require '[clojure.string :as str])
(let [[f & r] (str/split (slurp "foo.txt") #"\n")]
   ... do something with f and r ...)

ED: Somehow I failed to recognize Michał's answer and thought about deleting it, but since it's a little different and shows clojure.string.split, I won't.

danlei
when i output this to a file I get alot of [\ inside the file. Do you know why?
bleakgadfly
In this solution, the string returned by slurp is split in lines. That means, (str/split str #"\n") will return a vector of lines. Then, the first line is bound to f, and the rest of the vector to r. See the also the second paragraph of Michał's answer.
danlei
i tried your solution and did a (println (str f r)). The first line is perfect but the rest is in parantheses (typo) and quotes. like this: This is the first line.("" " And this is the" "other lines"). Any way to get rid of the parantheses and quotes? Cant see how Michaels solution solves that problem.
bleakgadfly
danlei
In other words: If you want "a string containing the rest of the file's contents", Michał's last snippet using (.split #"\n" str 2) is the way to go, but if you want to have the lines one by one, you could use Michał's first snippet or my solution. Typo in my previous comment: (seq (.split #"\n" str 2))
danlei