Walk Directory
From Rosetta Code
Programming Task
This is a programming task. It lays out a problem which Rosetta Code users are encouraged to solve, using languages they know.
Walk a given directory and print the names of files matching a given pattern.
Note: This task is for non-recursive methods. These tasks should read a single directory, not an entire directory tree. For code examples that read entire directory trees, see Walk Directory Tree
Note: Please be careful when running any code presented here.
Contents |
[edit] Ada
Works with: GCC version 4.12
with Ada.Directories; use Ada.Directories; with Ada.Text_IO; use Ada.Text_IO; procedure Walk_Directory (Directory : in String := "."; Pattern : in String := "") -- empty pattern = all file names/subdirectory names is Search : Search_Type; Dir_Ent : Directory_Entry_Type; begin Start_Search (Search, Directory, Pattern); while More_Entries (Search) loop Get_Next_Entry (Search, Dir_Ent); Put_Line (Simple_Name (Dir_Ent)); end loop; End_Search (Search); end Walk_Directory;
[edit] C
Works with: gcc version 4.0.1
Platform: BSD
In this example, the pattern is a POSIX extended regular expression.
#include <sys/types.h>
#include <dirent.h>
#include <regex.h>
#include <stdio.h>
void walker(const char *dir, const char *pattern)
{
struct dirent *entry;
regex_t reg;
DIR *d;
if (regcomp(®, pattern, REG_EXTENDED | REG_NOSUB))
return;
if (!(d = opendir(dir)))
return;
while (entry = readdir(d))
if (!regexec(®, entry->d_name, 0, NULL, 0))
puts(entry->d_name);
closedir(d);
}
int main()
{
walker(".", ".\\.c$");
return 0;
}
[edit] ColdFusion
This example display all files and directories directly under C:\temp that end with .html
<cfdirectory action="list" directory="C:\temp" filter="*.html" name="dirListing"> <cfoutput query="dirListing"> #dirListing.name# (#dirListing.type#)<br> </cfoutput>
[edit] Common Lisp
(defun walk-directory (directory pattern) (directory (merge-pathnames pattern directory)))
Uses the filename pattern syntax provided by the CL implementation.
[edit] D
See also the D code at Walk Directory Tree.
import std.stdio;
import std.file;
import std.path ;
void main(string[] args) {
auto path = args.length > 1 ? args[1] : "." ; // default current
auto pattern = args.length > 2 ? args[2] : "*.*"; // default all file
bool matchNPrint(DirEntry* de){
if(!de.isdir && fnmatch(de.name, pattern))
writefln(de.name) ;
return true ; // continue
}
listdir(path, &matchNPrint) ;
}
[edit] E
def walkDirectory(directory, pattern) {
for name => file ? (name =~ rx`.*$pattern.*`) in directory {
println(name)
}
}
Example:
? walkDirectory(<file:~>, "bash_") .bash_history .bash_profile .bash_profile~
[edit] Forth
Works with: gforth version 0.6.2
Gforth's directory walking functions are tied to the POSIX dirent functions, used by the C langauge entry above. Forth doesn't have regex support, so a simple filter function is used instead.
defer ls-filter ( name len -- ? )
: ls-all 2drop true ;
: ls-visible drop c@ [char] . <> ;
: ls ( dir len -- )
open-dir throw ( dirid )
begin
dup pad 256 rot read-dir throw
while
pad over ls-filter if
cr pad swap type
else drop then
repeat
drop close-dir throw ;
\ only show C language source and header files (*.c *.h)
: c-file? ( str len -- ? )
dup 3 < if 2drop false exit then
+ 1- dup c@
dup [char] c <> swap [char] h <> and if drop false exit then
1- dup c@ [char] . <> if drop false exit then
drop true ;
' c-file? is ls-filter
s" ." ls
[edit] Groovy
// *** print *.txt files in current directory
new File('.').eachFileMatch(~/.*\.txt/) {
println it
}
// *** print *.txt files in /foo/bar
new File('/foo/bar').eachFileMatch(~/.*\.txt/) {
println it
}
[edit] Haskell
Works with: GHCi version 6.6
In this example, the pattern is a POSIX extended regular expression.
import System.Directory
import Text.Regex
walk :: FilePath -> String -> IO ()
walk dir pattern = do
filenames <- getDirectoryContents dir
putStr $ unlines $ filter ((/= Nothing).(matchRegex $ mkRegex pattern)) filenames
main = walk "." ".\\.hs$"
[edit] IDL
f = file_search('*.txt', count=cc)
if cc gt 0 then print,f
(IDL is an array language - very few things are ever done in 'loops'.)
[edit] MAXScript
getFiles "C:\\*.txt"
[edit] OCaml
#load "str.cma" let contents = Array.to_list (Sys.readdir ".") in let select pat str = Str.string_match (Str.regexp pat) str 0 in List.filter (select ".*\\.jpg") contents
[edit] Perl
opendir my $dh, 'the_directory';
print map {"$_\n"} grep /foo/, readdir $dh;
closedir $dh;
[edit] PHP
Works with: PHP version 5.2.0
$pattern = 'php';
$dh = opendir('c:/foo/bar'); // Or '/home/foo/bar' for Linux
while (false !== ($file = readdir($dh)))
{
if ($file != '.' and $file != '..')
{
if (preg_match("/$pattern/", $file))
{
echo "$file matches $pattern\n";
}
}
}
Works with: PHP version 4 >= 4.3.0 or 5
foreach (glob('/home/foo/bar/*.php') as $file){
echo "$file\n";
}
[edit] Pop11
Built-in procedure sys_file_match searches directories (or directory trees) using shell-like patterns:
lvars repp, fil;
;;; create path repeater
sys_file_match('*.p', '', false, 0) -> repp;
;;; iterate over files
while (repp() ->> fil) /= termin do
;;; print the file
printf(fil, '%s\n');
endwhile;
[edit] Python
The glob library included with Python lists files matching shell-like patterns:
import glob for filename in glob.glob('*'): print filename
[edit] Raven
'dir://.' open each as item
item m/\.txt$/ if "%(item)s\n" print
[edit] Ruby
# Files under this directory:
Dir.glob('*') { |file| puts file }
# Files under path '/foo/bar':
Dir.glob( File.join('/foo/bar', '*') ) { |file| puts file }
# As a method
def file_match(pattern=/\.txt/, path='.')
Dir[File.join(path,'*')].each do |file|
puts file if file =~ pattern
end
end
[edit] Tcl
foreach var [glob *.txt] { puts $var }
[edit] Toka
As with the C example, this uses a a POSIX extended regular expression as the pattern. The dir.listByPattern function used here was introduced in library revision 1.3.
needs shell " ." " .\\.txt$" dir.listByPattern
[edit] Visual Basic .NET
Works with: Visual Basic .NET version 9.0+
'Using the OS pattern matching
For Each file In IO.Directory.GetFiles("\temp", "*.txt")
Console.WriteLine(file)
Next
'Using VB's pattern matching and LINQ
For Each file In (From name In IO.Directory.GetFiles("\temp") Where name Like "*.txt")
Console.WriteLine(file)
Next
'Using VB's pattern matching and dot-notation
For Each file In IO.Directory.GetFiles("\temp").Where(Function(f) f Like "*.txt")
Console.WriteLine(file)
Next
[edit] UnixPipes
ls can take a file globbing pattern too. here using grep for regexp.
ls | grep '\.c$'
Categories: Programming Tasks | File System Operations | Ada | C | ColdFusion | Common Lisp | D | E | Forth | Groovy | Haskell | IDL | MAXScript | OCaml | Perl | PHP | Pop11 | Python | Raven | Ruby | Tcl | Toka | Visual Basic .NET | UnixPipes

