How to list all subdirectories of a parent directory using Julia

I am looking to understand how to list all the subdirectories of a main directory using Julia. In shell script I would do something like this:

ls -d Simulations/SHmaxSv_*/*/ > dirNames.dat

I naively tried to do something like this, but it does not work:

julia> run(`ls -d Simulations/SHmaxSv_"*"/"*"/`)
ls: cannot access 'Simulations/SHmaxSv_*/*/': No such file or directory
ERROR: failed process: Process(`ls -d 'Simulations/SHmaxSv_*/*/'`, ProcessExited(2)) [2]

Stacktrace:
 [1] pipeline_error at ./process.jl:525 [inlined]
 [2] run(::Cmd; wait::Bool) at ./process.jl:440
 [3] run(::Cmd) at ./process.jl:438
 [4] top-level scope at none:1

let me know if anyone can help!

What is your current working directory? Use pwd()
you might have to change directory to the place where Silulations is located

Also I would tend to use a find for this
find Directory - type d

So there is readdir, which lists the files in a given folder.
Combining it with isdir should work.

filter(isdir,readdir(path))

maybe you have to pass join=true to get the full path.
If you want the filename back there is basename.

fulldirpaths=filter(isdir,readdir(path,join=true))
dirnames=basename.(fulldirpaths)

Further info:
https://docs.julialang.org/en/v1/base/file/

5 Likes

That’s because the filename expansion is not done by ls but by your shell and Julia Cmd objects are intentionally not trying to mimic a shell. You can call the shell yourself though. Something like this should work:

readlines(`sh -c "ls -d Simulations/SHmaxSv_*/*/"`)

To find directories with Julia code, readdir and walkdir are your primary tools.

The solution proposed by @GunnarFarneback works. However, I am still curious how I would obtain the same results using readdir and walkdir. Could you comment on it?

Below is what I get when I use the proposed solution:

julia> lines = readlines(`sh -c "ls -d Simulations/SHmaxSv_*/*/"`)
70-element Array{String,1}:
 "Simulations/SHmaxSv_1.1/ShminSv_0.65/"
 "Simulations/SHmaxSv_1.1/ShminSv_0.82/"
 "Simulations/SHmaxSv_1.1/ShminSv_0.9/"
 "Simulations/SHmaxSv_1.1/ShminSv_1.07/"
 "Simulations/SHmaxSv_1.1/ShminSv_1.15/"
 "Simulations/SHmaxSv_1.1/ShminSv_1.23/"
 ....

The Base functions don’t support glob matching, but you can use the Glob package:

using Glob
filter(isdir, readdir(glob"Simulations/SHmaxSv_*/*"))
2 Likes