newbie question: how to selectively iterate through a tree of directories ?

86 views
Skip to first unread message

hpw...@gmail.com

unread,
Oct 3, 2015, 10:44:22 AM10/3/15
to Clojure
Under linux, I have a tree of directories like this:
/path/top
/path/top/dir1  (in here there are two files f1, f2)
/path/top/dir2 -> /another-path/dir2 (a symbolic link) 
                 and under /another-path/dir2 there are two files g1, g2
If I use below code, I would get a list of files f1, f2, and g1, g2
(def directory (clojure.java.io/file "/path/top"))
(def files 
    (for [file (file-seq directory)] (.getName file)))
(files)
BUT I want to skip traversing the directory dir2 since it is a symbolic link.
i.e. the list of files that I want to get is f1, f2 only.
Could you please suggest a way to do this ?
THanks
HP

Gary Verhaegen

unread,
Oct 3, 2015, 11:59:40 AM10/3/15
to clo...@googlegroups.com
I'm on Windows at the moment, so I can't test, but I think you can
filter on isFile:

(for [file (file-seq dir)
:where (.isFile file)]
(.getName file))

should work, I think.
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

hpw...@gmail.com

unread,
Oct 3, 2015, 5:14:51 PM10/3/15
to Clojure
The directory structure is
   /path/top/dir1
   /path/top/dir1/f1
   /path/top/dir1/f2
   /path/top/dir2 -> /another/path/dir2 
----------
   /another/path/dir2/g1
   /another/path/dir2/g2

I tried this (following suggestion):
   
  (for [file (file-seq dir) :while (.isFile file)] (.getPath file))

It prints out a list with following items:
  /path/top/dir1/f1
  /path/top/dir1/f2
  /path/top/dir2/g1
  /path/top/dir2/g2

BUT the last two items are the ones that I do NOT want.
So, I guess I will need to tweak  file-seq so that it will NOT traverse
/path/top/dir2  since it is a symbolic link.

Is there anyway to tweak file-seq ??

THanks
HP

Gary Verhaegen

unread,
Oct 4, 2015, 2:24:49 AM10/4/15
to clo...@googlegroups.com
Sorry, I meant :when, not :where. Though it won't change the problem.

Here's the rub: first file-seq produces its whole seq, then for comes along and filters out some of it. So (ignoring lazyness) file-seq ha already traversed symbolic links (at least for folders) by the time for sees it.

I fear you'll have to write your own file traversal function. Fortunately, it's not that hard. You can probably start from one of the examples here:

Andy-

unread,
Oct 5, 2015, 6:03:28 PM10/5/15
to Clojure
Reply all
Reply to author
Forward
0 new messages