Walk a directory/Recursively: Difference between revisions
m
→{{header|Wren}}: Minor tidy
No edit summary |
m (→{{header|Wren}}: Minor tidy) |
||
(39 intermediate revisions by 20 users not shown) | |||
Line 15:
* [[Walk a directory/Non-recursively]] (read a ''single directory'').
<br><br>
=={{header|11l}}==
{{trans|Nim}}
<syntaxhighlight lang="11l">L(filename) fs:walk_dir(‘/’)
I re:‘.*\.mp3’.match(filename)
print(filename)</syntaxhighlight>
=={{header|8th}}==
<
"*.c" f:rglob \ top of stack now has list of all "*.c" files, recursively
</syntaxhighlight>
=={{header|Ada}}==
<
with Ada.Text_IO;
Line 45 ⟶ 52:
begin
Walk (".", "*.adb");
end Test_Directory_Walk;</
The solution first enumerates files in a directory, that includes the subdirectories, if their names match the pattern. Then it steps down into each of the subdirectories. The pseudo directories . and .. are excluded. The behavior upon symbolic links depends on the [[OS]] and the implementation of the Ada.Directories package.
Line 52 ⟶ 59:
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386 - uses non-standard library routines ''get directory'' and'' grep in string''.}}
<!-- {{does not work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386 - ''get directory'' and'' grep in string'' not available in any library ... yet}} -->
<
STRING slash = "/", pwd=".", parent="..";
Line 78 ⟶ 85:
FI;
walk tree(".", match sort a68 and print)</
{{out|Sample output}}
<pre>
Line 93 ⟶ 100:
./Permutation_Sort.a68
</pre>
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">; list all files at current path
print list.recursive "."
; get all files at given path
; and select only the ones we want
; just select the files with .md extension
select list.recursive "some/path"
=> [".md" = extract.extension]
; just select the files that contain "test"
select list.recursive "some/path"
=> [in? "test"]</syntaxhighlight>
=={{header|AutoHotkey}}==
Display all TMP files in Temp directory and its subdirectories.
<
out .= A_LoopFileName "`n"
MsgBox,% out</
=={{header|BaCon}}==
This line will recursively walk though all directories starting from the current directory ".":
<
=={{header|Batch File}}==
A sample code that displays all the EXE files in System32 directory recursively.
<
----
If you wanted to apply some command to each item in a directory tree, then use <code>FOR</code> with the switch <code>/R</code>. For example, to apply the ECHO command to every DLL file in C:\Windows\System32:
{{works with|Windows NT|4 or later (includes Windows XP and onward)}}
<
This can be done from outside a batch file (entered directly at the command prompt) by changing the double percent signs (%%) to single percents (%):
<
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
pattern$ = "*.chm"
PROClisttree(directory$, pattern$)
Line 143 ⟶ 166:
SYS "FindClose", sh%
ENDIF
ENDPROC</
=={{header|C}}==
==={{libheader|POSIX}}===
{{works with|POSIX|.1-2001}}
<
#include <sys/stat.h>
#include <unistd.h>
Line 250 ⟶ 273:
}
return 0;
}</
==={{libheader|BSD libc}}===
With the [http://www.openbsd.org/cgi-bin/man.cgi?query=fts&apropos=0&sektion=3&manpath=OpenBSD+Current&arch=i386&format=html fts(3)] functions from 4.4BSD, this program can sort the files, and can also detect cycles (when a link puts a directory inside itself). This program makes a ''logical traversal'' that follows symbolic links to directories.
{{works with|OpenBSD|4.9}}
<
#include <err.h>
#include <errno.h>
Line 337 ⟶ 360:
pmatch(".", "*.c");
return 0;
}</
=== [[Windows]] ===
{{libheader|Win32}}
{{works with|MinGW}}
<
#include <stdio.h>
#include <stdlib.h>
Line 578 ⟶ 601:
return 0;
}</
=={{header|C sharp|C#}}==
<
using System.Collections.Generic;
using System.IO;
Line 618 ⟶ 641:
}
}
</syntaxhighlight>
=={{header|C++}}==
{{libheader|boost}}
<
#include "boost/regex.hpp"
#include <iostream>
Line 640 ⟶ 663:
std::cout << iter->path() << "\n";
}
}</
{{libheader|std|C++17}}
<
#include <filesystem>
#include <iostream>
Line 656 ⟶ 679:
std::cout << file.path().filename().string() << std::endl;
}
}</
=={{header|Caché ObjectScript}}==
<
Class Utils.File [ Abstract ]
{
Line 683 ⟶ 706:
}
</syntaxhighlight>
{{out|Example}}
Line 702 ⟶ 725:
=={{header|Clojure}}==
The standard function ''file-seq'' does a tree walk.
<
(defn walk [dirpath pattern]
Line 709 ⟶ 732:
(map #(println (.getPath %)) (walk "src" #".*\.clj"))
</syntaxhighlight>
=={{header|CoffeeScript}}==
{{works with|node.js}}
<
walk = (dir, f_match, f_visit) ->
Line 729 ⟶ 752:
matcher = (fn) -> fn.match /\.coffee/
action = console.log
walk dir, matcher, action</
=={{header|Common Lisp}}==
{{libheader|CL-FAD}}
This example uses the <code>CL-FAD</code> library to achieve compatibility where the ANSI CL standard leaves ambiguities about pathnames. Quicklisp is used to ensure it is loaded. Traversal is depth-first unless <code>:depth-first-p nil</code> is passed.
<
(defun mapc-directory-tree (fn directory &key (depth-first-p t))
(dolist (entry (cl-fad:list-directory directory))
Line 743 ⟶ 766:
(when depth-first-p
(funcall fn entry))))
</syntaxhighlight>
<
(when (equal (pathname-type x) "lisp")
(write-line (namestring x))))
Line 754 ⟶ 777:
/home/sthalik/lang/lisp/box-muller.lisp
/home/sthalik/lang/lisp/displaced-subseq.lisp
[...]</
=={{header|D}}==
<
import std.stdio, std.file;
Line 763 ⟶ 786:
// a depth-first scan):
dirEntries("", "*.d", SpanMode.breadth).writeln;
}</
=={{header|Dart}}==
<syntaxhighlight lang="dart">
import 'dart:io' show Directory, Platform, File;
void main(List<String> args) {
var dir = Directory(args[0]);
dir.list(recursive: true, followLinks: false).forEach((final cur) {
if (cur is Directory) {
print("Directory: ${cur.path}");
}
if (cur is File) {
print("File: ${cur.path}");
}
});
}
</syntaxhighlight>
=={{header|Delphi}}==
{{libheader| System.IOUtils}}
<syntaxhighlight lang="delphi">
program Walk_a_directory;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.IOUtils;
var
Files: TArray<string>;
FileName, Directory: string;
begin
Directory := TDirectory.GetCurrentDirectory; // dir = '.', work to
Files := TDirectory.GetFiles(Directory, '*.*', TSearchOption.soAllDirectories);
for FileName in Files do
begin
Writeln(FileName);
end;
Readln;
end.
</syntaxhighlight>
=={{header|E}}==
<
for name => file in directory {
if (name =~ rx`.*$pattern.*`) {
Line 775 ⟶ 844:
}
}
}</
{{out|Example}}
<
/usr/share/man/man1/rmdir.1
/usr/share/man/man2/rmdir.2</
=={{header|Elixir}}==
<
def recursive(dir \\ ".") do
Enum.each(File.ls!(dir), fn file ->
Line 791 ⟶ 860:
end
Walk_directory.recursive</
{{out}}
Line 810 ⟶ 879:
=={{header|Emacs Lisp}}==
<
("/tmp/el/1/c.el" "/tmp/el/a.el" "/tmp/el/b.el")</
=={{header|Erlang}}==
Use the builtin function [http://erlang.org/doc/man/filelib.html#fold_files-5 filelib:fold_files/5].
{{out}}
<syntaxhighlight lang="erlang">
walk_dir(Path, Pattern) ->
filelib:fold_files(
Path,
Pattern,
true, % Recurse
fun(File, Accumulator) -> [File|Accumulator] end,
[]
)
</syntaxhighlight>
<syntaxhighlight lang="erlang">
% Collect every file in the current directory
walkdir:walk_dir(".", ".*").
% Collect every file my .config folder that ends with `rc`
walkdir:walk_dir("/home/me/.config/", ".*rc$").
</syntaxhighlight>
=={{header|F_Sharp|F#}}==
This code is tail-recursive and lazy.
<
let rec getAllFiles dir pattern =
Line 836 ⟶ 915:
getAllFiles "c:\\temp" "*.xml"
|> Seq.iter (printfn "%s")</
=={{header|Factor}}==
<
"." t [
dup ".factor" tail? [ print ] [ drop ] if
] each-file</
=={{header|Forth}}==
{{works with|gforth|0.7.9}}
<
require unix/filestat.fs
require unix/libc.fs
Line 895 ⟶ 974:
s" ." ls-r cr
</syntaxhighlight>
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">#include "dir.bi"
Sub listFiles(Byref filespec As String, Byval attrib As Integer)
Dim As Integer count = 0
Dim As String filename = Dir(filespec, attrib)
Do While Len(filename) > 0
count += 1
Print filename
filename = Dir()
Loop
Print !"\nArchives count:"; count
End Sub
Dim As String mylist = "C:\FreeBASIC\""
Print "Directories:"
listFiles(mylist & "*", fbDirectory)
Print
Print "Archive files:"
listFiles(mylist & "*", fbArchive)
Sleep</syntaxhighlight>
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
void local fn EnumerateDirectoryAtURL( dirURL as CFURLRef )
NSDirectoryEnumerationOptions options = NSDirectoryEnumerationSkipsPackageDescendants + ¬
NSDirectoryEnumerationSkipsHiddenFiles
DirectoryEnumeratorRef enumerator = fn FileManagerEnumeratorAtURL( dirURL, NULL, options, NULL, NULL )
CFURLRef url = fn EnumeratorNextObject( enumerator )
while ( url )
if ( fn StringIsEqual( fn URLPathExtension( url ), @"fb" ) )
NSLog(@"%@",url)
end if
url = fn EnumeratorNextObject( enumerator )
wend
end fn
fn EnumerateDirectoryAtURL( fn FileManagerURLForDirectory( NSDesktopDirectory, NSUserDomainMask ) )
HandleEvents
</syntaxhighlight>
=={{header|Gambas}}==
'''[https://gambas-playground.proko.eu/?gist=f48f8d5c2e2e85a8f80bcdc0124a35a5 Click this link to run this code]'''
<
Dim sTemp As String
Line 906 ⟶ 1,031:
Next
End</
Output:
<pre>
Line 920 ⟶ 1,045:
=={{header|GAP}}==
<
local dir, file, e;
dir := Directory(name);
Line 936 ⟶ 1,061:
# This will print filenames
Walk(".", Display);</
=={{header|Go}}==
<
import (
Line 968 ⟶ 1,093:
func main() {
filepath.Walk("/", VisitFile)
}</
=={{header|Groovy}}==
Search text files in current directory tree in a depth-first fashion:
<
if (it.name =~ /.*\.txt/) println it;
}</
Shorter variant:
<
Variant processing only files:
<
Flexible search, traversal can be adapted by providing various options in the options Map, see documentation of method:
[http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/File.html#traverse(java.util.Map,%20groovy.lang.Closure) traverse(Map options, Closure closure)]
<
type : FILES,
nameFilter : ~/.*\.txt/,
preDir : { if (it.name == '.svn') return SKIP_SUBTREE },
) { println it }
</syntaxhighlight>
=={{header|GUISS}}==
Here we list all files that match the pattern m*.txt in "My Documents" and all of its subfolders:
<
Inputbox: filename>m*.txt,Button:Search</
=={{header|Haskell}}==
Line 1,001 ⟶ 1,126:
Using the packages [http://hackage.haskell.org/package/directory-1.2.5.0/docs/System-Directory.html#v:getCurrentDirectory directory] and [https://hackage.haskell.org/package/filemanip-0.3.6.3/docs/System-FilePath-Find.html#v:find filemanip]
<
import System.Directory
import System.FilePath.Find
search pat
main = do
[pat] <- getArgs
dir <- getCurrentDirectory
files <- search pat dir
mapM_ putStrLn files</syntaxhighlight>
or more classic way:
<
import System.Directory
import System.IO
isDirectory <- doesDirectoryExist top
if isDirectory
then do
files <- listDirectory top
mapM_ (dirWalk
else filefunc top
main :: IO ()
main = do
|
| otherwise = return
dirWalk worker "."</syntaxhighlight>
== Icon and Unicon ==
Line 1,042 ⟶ 1,164:
Icon doesn't support 'stat' or 'open' of a directory; however, information can be obtained by use of the <code>system</code> function to access command line.
==={{header|Unicon}}===
<syntaxhighlight lang="unicon">
###########################
# A sequential solution #
Line 1,115 ⟶ 1,237:
return D
}
end</
=={{header|IDL}}==
<
This will descend down the directory/ies in the variable <tt>"directory"</tt> (which can be an array) returning an array of strings with the names of the files matching "*.txt" and placing the total number of matches into the variable <tt>"cc"</tt>
=={{header|J}}==
<
>{."1 dirtree '*.html'</
The verb <tt>dirtree</tt> returns a file listing of a directory tree as a boxed matrix with file names in the first column. The primitives <tt>>{."1</tt> will return the unboxed contents of the first column.
Line 1,132 ⟶ 1,254:
{{works with|Java|1.4+}}
Done using no pattern. But with end string comparison which gave better results.
<
public class MainEntry {
Line 1,160 ⟶ 1,282:
}
}
}</
{{works with|Java|7+}}
Luckily, <code>java.nio.file.Files</code> gives us a <code>walkFileTree</code> method that does exactly what this task calls for.
<
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
Line 1,181 ⟶ 1,303:
});
}
}</
{{works with|Java|8+}}
<
import java.nio.file.*;
Line 1,195 ⟶ 1,317:
}
}
</syntaxhighlight>
=={{header|JavaScript}}==
{{works with|JScript}}
<
function walkDirectoryTree(folder, folder_name, re_pattern) {
Line 1,228 ⟶ 1,350:
}
walkDirectoryTree(dir, dir.name, '\\.txt$');</
=={{header|Julia}}==
{{works with|Julia|1.2}}
<
pattern = r".mp3$"
Line 1,240 ⟶ 1,362:
if occursin(pattern, file) println(file) end
end
end</
=={{header|Kotlin}}==
<
import java.io.File
Line 1,257 ⟶ 1,379:
for (file in files) println(file)
}
</syntaxhighlight>
Output (Ubuntu 14.04):
Line 1,270 ⟶ 1,392:
=={{header|Lasso}}==
<
define dir -> eachVisibleFilePath() => {
return with name in self -> eachEntry where #name -> second != io_dir_dt_dir where not(#name -> first -> beginswith('.')) select .makeFullPath(#name -> first)
Line 1,299 ⟶ 1,421:
do #matchingfilenames -> insert(#filename)
#matchingfilenames</
-> array(myfile.lasso, test.lasso, rosetta.lasso)
=={{header|LiveCode}}==
<syntaxhighlight lang="livecode">function pathsForDirectoryAndWildcardPattern pDirectory, pWildcardPattern
-- returns a return-delimited list of long file names
-- the last character in the list is a return, unless the list is empty
filter files(pDirectory) with pWildcardPattern
repeat for each line tFile
put pDirectory & slash & tFile & cr after tPaths
end repeat
filter folders(pDirectory) without ".."
repeat for each line tFolder
put pathsForDirectoryAndWildcardPattern(pDirectory & slash & tFolder, pWildcardPattern) after tPaths
end repeat
return tPaths
end pathsForDirectoryAndWildcardPattern</syntaxhighlight>
Example
<syntaxhighlight lang="livecode">put pathsForDirectoryAndWildcardPattern(the documents folder, "*.livecode*"</syntaxhighlight>
Output
<pre>...
/Users/xxx/
/Users/xxx/
...</pre>
<nowiki>--~~~~</nowiki>
=={{header|Lua}}==
Lua itself is extremely spartanic as it is meant for embedding. As lfs (LuaFileSystem) is about as standard an extension as it gets, we use that.
<syntaxhighlight lang="lua">local lfs = require("lfs")
-- This function takes two arguments:
-- - the directory to walk recursively;
-- - an optional function that takes a file name as argument, and returns a boolean.
function find(self, fn)
return coroutine.wrap(function()
for f in lfs.dir(self) do
if f ~= "." and f ~= ".." then
local _f = self .. "/" .. f
if not fn or fn(_f) then
coroutine.yield(_f)
end
if lfs.attributes(_f, "mode") == "directory" then
for n in find(_f, fn) do
coroutine.yield(n)
end
end
end
end
end)
end
-- Examples
-- List all files and directories
for f in find("directory") do
print(f)
end
-- List lua files
for f in find("directory", function(self) return self:match("%.lua$") end) do
print(f)
end
-- List directories
for f in find("directory", function(self) return "directory" == lfs.attributes(self, "mode") end) do
print(f)
end</syntaxhighlight>
Lua provides functions such as os.execute([command]) and io.popen(prog [, mode]). Below an example for Windows users having io.popen at their disposal. Mind you, it may pop-up a command window.
<
-- Note that io.popen is not available on all platforms
local function getOutput(prog)
Line 1,361 ⟶ 1,523:
print(filename)
end
end</
=={{header|Mathematica}}/{{header|Wolfram Language}}==
The built-in function <code>FileNames</code> does exactly this:
:<code>FileNames[]</code> lists all files in the current working directory.
Line 1,371 ⟶ 1,533:
:<code>FileNames[forms,dirs,n]</code> includes files that are in subdirectories up to n levels down.
Examples (find all files in current directory, find all png files in root directory, find all files on the hard drive):
<
FileNames["*.png", $RootDirectory]
FileNames["*", {"*"}, Infinity]</
the result can be printed with Print /@ FileNames[....]
=={{header|MATLAB}} / {{header|Octave}}==
<
f = dir(fullfile(d,pattern));
for k = 1:length(f)
Line 1,390 ⟶ 1,552:
end;
end;
end; </
=={{header|MAXScript}}==
<
(
dirArr = GetDirectories (dir + "\\*")
Line 1,410 ⟶ 1,572:
)
walkDir "C:" "*.txt"</
=={{header|MoonScript}}==
MoonScript compiles to Lua, which itself is extremely spartanic as it is meant for embedding. As lfs (LuaFileSystem) is about as standard an extension as it gets, we use that.
<syntaxhighlight lang="moonscript">lfs = require "lfs"
-- This function takes two arguments:
-- - the directory to walk recursively;
-- - an optional function that takes a file name as argument, and returns a boolean.
find = (fn) => coroutine.wrap ->
for f in lfs.dir @
if f ~= "." and f ~= ".."
_f = @.."/"..f
coroutine.yield _f if not fn or fn _f
if lfs.attributes(_f, "mode") == "directory"
coroutine.yield n for n in find _f, fn
-- Examples
-- List all files
print f for f in find "templates"
-- List moonscript files
print f for f in find "templates", => @\match "%.moon$"
-- List directories
print f for f in find "templates", => "directory" == lfs.attributes @, "mode"</syntaxhighlight>
=={{header|Nanoquery}}==
<
def get_files(dirname)
Line 1,438 ⟶ 1,626:
println file
end
end</
=={{header|Nim}}==
The “os” standard module provides an iterator to walk recursively a directory. The iterator allows some filtering about the kind of entry to consider: real files (default), symbolic links to files, directories, symbolic links to directories. It doesn’t allow to specify a pattern, so filtering on name should be done using another mechanism (for instance, regular expressions).
<syntaxhighlight lang="nim">import os, re
for file in walkDirRec "/":
if file.match re".*\.mp3":
echo file</
=={{header|Objeck}}==
<
class Test {
Line 1,475 ⟶ 1,665:
};
}
}</
=={{header|Objective-C}}==
<
NSDirectoryEnumerator *de = [[NSFileManager defaultManager] enumeratorAtPath:dir];
for (NSString *file in de)
if ([[file pathExtension] isEqualToString:@"mp3"])
NSLog(@"%@", file);</
=={{header|OCaml}}==
<
#load "unix.cma"
#load "str.cma"
Line 1,516 ⟶ 1,706:
let results = walk_directory_tree "/usr/local/lib/ocaml" ".*\\.cma" in
List.iter print_endline results;
;;</
=={{header|ooRexx}}==
===version 1===
<
* List all file names on my disk D: that contain the string TTTT
*--------------------------------------------------------------------*/
Line 1,529 ⟶ 1,719:
If pos('TTTT',translate(file.i))>0 Then
say file.i
end</
{{out}}
<pre>1127869 files on disk
Line 1,537 ⟶ 1,727:
===version 2===
Get only files matching the file-spec.
<
* List all file names on my disk D: that contain the string TTTT
*--------------------------------------------------------------------*/
Line 1,546 ⟶ 1,736:
If pos('TTTT',translate(file.i))>0 Then
say file.i
end </
{{out}}
<pre>3 files found
Line 1,554 ⟶ 1,744:
=={{header|Oz}}==
<
[Path] = {Module.link ['x-oz://system/os/Path.ozf']}
[Regex] = {Module.link ['x-oz://contrib/regex']}
Line 1,572 ⟶ 1,762:
end
in
{WalkDirTree "." ".*\\.oz$" System.showInfo}</
=={{header|Perl}}==
Line 1,579 ⟶ 1,769:
{{works with|Perl|5.x}}
<
my $dir = '.';
my $pattern = 'foo';
my $callback = sub { print $File::Find::name, "\n" if /$pattern/ };
find $callback, $dir;</
Or if you need maximum performance and are on a 'nix system, open a pipe to the GNU <tt>find</tt> program:
<
sub find_files {
Line 1,599 ⟶ 1,789:
}
find_files('.', '*.mp3');</
Or using the recently popular Path::Tiny
<syntaxhighlight lang="perl">#!/usr/bin/perl
use strict; # https://rosettacode.org/wiki/Walk_a_directory/Recursively
use warnings;
use Path::Tiny;
path('.')->visit( sub {/\.c$/ and print "$_\n"}, {recurse => 1} );</syntaxhighlight>
=={{header|Phix}}==
{{libheader|Phix/basics}}
There is a builtin routine for this, walk_dir() - if interested you can find the full implementation in builtins\file.e (an autoinclude).
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">function</span> <span style="color: #000000;">find_pfile</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">pathname</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">dirent</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"pfile.e"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dirent</span><span style="color: #0000FF;">[</span><span style="color: #000000;">D_NAME</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- return pathname&dirent[D_NAME] -- as below</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">pathname</span><span style="color: #0000FF;">&</span><span style="color: #008000;">"\\"</span><span style="color: #0000FF;">&</span><span style="color: #000000;">dirent</span><span style="color: #0000FF;">[</span><span style="color: #000000;">D_NAME</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- non-zero terminates scan</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">walk_dir</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"C:\\Program Files (x86)\\Phix"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">find_pfile</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
Passing 1 as the third parameter makes it scan recursively.
{{out}}
Line 1,648 ⟶ 1,827:
=={{header|PHP}}==
<
$prefix = $dir . '/';
$dir = dir($dir);
Line 1,660 ⟶ 1,839:
}
}
findFiles('./foo', '/\.bar$/');</
This implementation uses Perl compatible regular expressions to match the whole path of the file
===PHP BFS (Breadth First Search)===
<syntaxhighlight lang="php">/*
This script performs a BFS search with recursion protection
it is often faster to search using this method across a
Line 1,752 ⟶ 1,931:
}
closedir($dh);
}</
=={{header|PicoLisp}}==
<
(recur (Dir)
(for F (dir Dir)
Line 1,763 ⟶ 1,942:
(recurse Path) ) # Yes: Recurse
((match '`(chop "s@.l") (chop F)) # Matches 's*.l'?
(println Path) ) ) ) ) ) ) # Yes: Print it</
{{out}}
<pre>"./src64/sym.l"
Line 1,771 ⟶ 1,950:
=={{header|Pop11}}==
Built-in procedure <code>sys_file_match</code> searches directories or directory trees using shell-like patterns (three dots indicate search for subdirectory tree).
<
;;; create path repeater
sys_file_match('.../*.p', '', false, 0) -> repp;
Line 1,778 ⟶ 1,957:
;;; print the path
printf(fil, '%s\n');
endwhile;</
=={{header|PowerShell}}==
In PowerShell the <code>Get-ChildItem</code> cmdlet allows for recursive filtering on file names with simple wildcards:
<
For more complex filtering criteria the result of <code>Get-ChildItem</code> can be piped into the <code>Where-Object</code> cmdlet:
<
Where-Object { $_.Name -match 'foo[0-9]' -and $_.Length -gt 5MB }</
To perform an action on every matching file the results can be piped into the <code>ForEach-Object</code> cmdlet:
<
Where-Object { $_.Name -match 'foo[0-9]' } |
ForEach-Object { ... }</
''Note:'' To include only ''files'' instead of directories too each of the above needs an additional<code>Where-Object</code> filter:
<
=={{header|Prolog}}==
{{works with|Swi-Prolog|8.3}}
<syntaxhighlight lang="prolog">
% submitted by Aykayayciti (Earl Lamont Montgomery)
% altered from fsaenzperez April 2019
% (swi-prolog.discourse-group)
test_run :-
proc_dir('C:\\vvvv\\vvvv_beta_39_x64').
proc_dir(Directory) :-
format('Directory: ~w~n',[Directory]),
directory_files(Directory,Files),!, %cut inserted
proc_files(Directory,Files).
proc_files(Directory, [File|Files]) :-
proc_file(Directory, File),!, %cut inserted
proc_files(Directory, Files).
proc_files(_Directory, []).
proc_file(Directory, File) :-
(
File = '.',
directory_file_path(Directory, File, Path),
exists_directory(Path),!,%cut inserted
format('Directory: ~w~n',[File])
;
File = '..',
directory_file_path(Directory, File, Path),
exists_directory(Path),!,%cut inserted
format('Directory: ~w~n',[File])
;
directory_file_path(Directory, File, Path),
exists_directory(Path),!,%cut inserted
proc_dir(Path)
;
directory_file_path(Directory, File, Path),
exists_file(Path),!,%cut inserted
format('File: ~w~n',[File])
;
format('Unknown: ~w~n',[File])
).</syntaxhighlight>
output :
<syntaxhighlight lang="prolog">?- test_run.
File: GMFBridge.ax
File: libeay32.dll
File: ssleay32.dll
File: license.txt
Directory: C:\vvvv\vvvv_beta_39_x64/licenses
Directory: .
Directory: ..
File: Apache.txt
File: BSD.txt
File: LGPL.txt
File: MIT.txt
File: MPL.txt
File: MS-PL-Eula.rtf
File: MS-PL.txt
File: MSR-SSLA.txt
</syntaxhighlight>
=={{header|PureBasic}}==
<
Static RegularExpression
If Not RegularExpression
Line 1,816 ⟶ 2,061:
EndIf
Wend
EndProcedure</
<
ExamineDirectory(1,"C:\WINDOWS\","")
WalkRecursive(1,"C:\WINDOWS\","\.log$")
FinishDirectory(1)</
=={{header|Prolog}}==
{{works with|Swi-Prolog|8.3}}
<syntaxhighlight lang="prolog">% submitted by Aykayayciti (Earl Lamont Montgomery)
% altered from fsaenzperez April 2019
% (swi-prolog.discourse-group)
test_run :-
proc_dir('C:\\vvvv\\vvvv_beta_39_x64').
proc_dir(Directory) :-
format('Directory: ~w~n',[Directory]),
directory_files(Directory,Files),!, %cut inserted
proc_files(Directory,Files).
proc_files(Directory, [File|Files]) :-
proc_file(Directory, File),!, %cut inserted
proc_files(Directory, Files).
proc_files(_Directory, []).
proc_file(Directory, File) :-
(
File = '.',
directory_file_path(Directory, File, Path),
exists_directory(Path),!,%cut inserted
format('Directory: ~w~n',[File])
;
File = '..',
directory_file_path(Directory, File, Path),
exists_directory(Path),!,%cut inserted
format('Directory: ~w~n',[File])
;
directory_file_path(Directory, File, Path),
exists_directory(Path),!,%cut inserted
proc_dir(Path)
;
directory_file_path(Directory, File, Path),
exists_file(Path),!,%cut inserted
format('File: ~w~n',[File])
;
format('Unknown: ~w~n',[File])
).</syntaxhighlight>
output :
<syntaxhighlight lang="prolog">?- test_run.
File: GMFBridge.ax
File: libeay32.dll
File: ssleay32.dll
File: license.txt
Directory: C:\vvvv\vvvv_beta_39_x64/licenses
Directory: .
Directory: ..
File: Apache.txt
File: BSD.txt
File: LGPL.txt
File: MIT.txt
File: MPL.txt
File: MS-PL-Eula.rtf
File: MS-PL.txt
File: MSR-SSLA.txt</syntaxhighlight>
=={{header|Python}}==
{{works with|Python|3.x}}
Use the standard [https://docs.python.org/3/library/pathlib.html#pathlib.Path.rglob pathlib.Path.rglob()] module to recursively walk a directory with optional filter.
<syntaxhighlight lang="python">
from pathlib import Path
for path in Path('.').rglob('*.*'):
print(path)
</syntaxhighlight>
{{works with|Python|3.x}}
{{works with|Python|2.3+}}
This uses the standard [http://docs.python.org/py3k/library/os.html?highlight=os.walk#os.walk os.walk()] module function to walk a directory tree, and the [http://docs.python.org/py3k/library/fnmatch.html fnmatch] module for matching file names.
<
import os
Line 1,834 ⟶ 2,151:
for root, dirs, files in os.walk(rootPath):
for filename in fnmatch.filter(files, pattern):
print( os.path.join(root, filename))</
{{works with|Python|<nowiki>2.x</nowiki>}}
{{works with|Python|<nowiki>3.x</nowiki>}}
A more strictly comparable port of this 2.3+ code to earlier versions of Python would be:
<
import os, os.path
Line 1,846 ⟶ 2,163:
print os.path.join(dir, filename)
os.path.walk('/', print_fnmatches, '*.mp3')</
The old ''os.path.walk'' function was a challenge for many to use because of the need to pass a function into the walk, and any arguments to that function through to it ... as shown. It's sometimes useful to pass mutable objects (lists, dictionaries, or instances of user-defined classes) to the inner function ... for example, to collect all the matching files for later processing.
Line 1,853 ⟶ 2,170:
{{libheader|Path}}
(''Note:'' This uses a non-standard replacement to the '''os.path''' module)
<
rootPath = '/'
Line 1,860 ⟶ 2,177:
d = path(rootPath)
for f in d.walkfiles(pattern):
print f</
=={{header|R}}==
<
=={{header|Racket}}==
<syntaxhighlight lang="racket">
-> (for ([f (in-directory "/tmp")] #:when (regexp-match? "\\.rkt$" f))
(displayln f))
... *.rkt files including in nested directories ...
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
Using the [https://github.com/tadzik/File-Find/ File::Find] module:
<syntaxhighlight lang="raku" line>use File::Find;
.say for find dir => '.', name => /'.txt' $/;</syntaxhighlight>
Alternatively, a custom solution that provides the same interface as the built-in (non-recursive) <tt>dir</tt> function, and uses <tt>gather</tt>/<tt>take</tt> to return a lazy sequence:
<syntaxhighlight lang="raku" line>sub find-files ($dir, Mu :$test) {
gather for dir $dir -> $path {
if $path.basename ~~ $test { take $path }
if $path.d { .take for find-files $path, :$test };
}
}
.put for find-files '.', test => /'.txt' $/;</syntaxhighlight>
Or if you value performance over portability, here's a function that runs the GNU <tt>find</tt> program and returns a lazy sequence of the files it finds. Parameters are not subjected to shell expansion, and the null-byte (which cannot be present in file paths) is used as the path delimiter, so it should be pretty safe.
<syntaxhighlight lang="raku" line>sub find-files ($dir, :$pattern) {
run('find', $dir, '-iname', $pattern, '-print0', :out, :nl«\0»).out.lines;
}
.say for find-files '.', pattern => '*.txt';</syntaxhighlight>
=={{header|Rascal}}==
<
module Walk
import String;
Line 1,884 ⟶ 2,228:
elseif (isDirectory(a+entry))
Walk(a+entry, pattern);
}</
=={{header|REALbasic}}==
<
For i As Integer = 1 To parentDir.Count
If parentDir.Item(i).Directory Then
Line 1,899 ⟶ 2,243:
End If
Next
End Sub</
Accepts a FolderItem object and a Regex pattern as a string:
<syntaxhighlight lang="vb">
Dim f As FolderItem = GetFolderItem("C:\Windows\system32")
Dim pattern As String = "((?:[a-z][a-z]+))(\.)(dll)" //all file names ending in .dll
printFiles(f, pattern)</
=={{header|Red}}==
<syntaxhighlight lang="red">Red []
walk: func [
"Walk a directory tree recursively, setting WORD to each file and evaluating BODY."
'word "For each file, set with the absolute file path."
directory [file!] "Starting directory."
body [block!] "Block to evaluate for each file, during which WORD is set."
/where
rules [block!] "Parse rules defining file names to include."
][
foreach file read directory [
if where [if not parse file rules [continue]]
either dir? file: rejoin [directory file] [walk item file body] [
set 'word file
do body
]
]
]
rules: compose [
any (charset [#"A" - #"Z"])
".TXT"
]
walk/where file %/home/user/ [print file] rules</syntaxhighlight>
=={{header|REXX}}==
Line 1,910 ⟶ 2,282:
{{works with|Regina}}
The following program was tested in a DOS window under Windows/XP and should work for all Microsoft Windows.
<
parse arg xdir; if xdir='' then xdir='\' /*Any DIR specified? Then use default.*/
@.=0 /*default result in case ADDRESS fails.*/
Line 1,927 ⟶ 2,299:
do j=1 for #; say @.j /*show all the files that met criteria.*/
end /*j*/
exit @.0+rc /*stick a fork in it, we're all done. */</
'''output''' when the following was used: <tt> I:\firefox*.exe </tt>
<pre>
Line 1,942 ⟶ 2,314:
{{trans|BATCH-file}}
Works on Windows with ooRexx and Regina (not much REXX code in it)
<
=={{header|Ring}}==
<
see "Testing DIR() " + nl
mylist = dir("C:\Ring")
Line 1,956 ⟶ 2,328:
next
see "Files count : " + len(mylist)
</syntaxhighlight>
Output:
<pre>
Line 1,986 ⟶ 2,358:
Using the Find core Module:
<
Find.find('/your/path') do |f|
# print file and path to screen if filename ends in ".mp3"
puts f if f.match(/\.mp3\Z/)
end</
A little less verbose example using a shortcut for the glob method of Dir:
<
=={{header|Rust}}==
Line 2,001 ⟶ 2,373:
Using std::fs::walk_dir (unstable as of Rust 1.1) with imperative for-loop:
<
use std::fs;
Line 2,013 ⟶ 2,385:
}
}
}</
=={{header|Scala}}==
This is not implemented in the Scala library. Here is a simple solution, building on [[Java]] class ''<code>java.io.File</code>'':
<
object `package` {
Line 2,033 ⟶ 2,405:
for(f <- walkTree(dir)) println(f)
for(f <- walkTree(dir) if f.getName.endsWith(".mp3")) println(f)
}</
=={{header|Scheme}}==
Varies slightly depending on the implementation of scheme.
{{works with|Chicken Scheme}}
<
(use files)
(use srfi-13)
Line 2,053 ⟶ 2,425:
(FN MYPATH) )))) (directory PATH #t) ))
(walk (lambda (X) (cond ((string-suffix? ".scm" X) (display X)(newline) ))) "/home/user/")</
See also: '''(find-files ...)''' function in the '''posix''' module.
{{works with|Gauche}}
<
(use srfi-13)
Line 2,069 ⟶ 2,441:
(FN MYPATH) )))) (directory-list PATH :add-path? #t :children? #t ) ))
(walk (lambda (X) (cond ((string-suffix? ".scm" X) (display X)(newline) ))) "/home/user/")</
See also: '''(find-file-in-paths ...)''' function in the '''file.util''' module.
{{works with|PLT Scheme}}
<
(require srfi/13)
Line 2,087 ⟶ 2,459:
(FN MYPATH) )))) (directory-list PATH)))
(walk (lambda (X) (cond ((string-suffix? ".scm" (path->string X)) (display X)(newline) ))) "/home/user/")</
See also: '''(find-files ...)''' function in the '''file''' module.
{{out|Sample output}}
Line 2,105 ⟶ 2,477:
[http://seed7.sourceforge.net/libraries/osfiles.htm#fileType%28in_string%29 fileType].
<
include "osfiles.s7i";
Line 2,127 ⟶ 2,499:
begin
walkDir(".", ".sd7");
end func;</
=={{header|Sidef}}==
<
dir.open(\var dir_h) || return nil
Line 2,151 ⟶ 2,523:
}
} => dir
)</
=={{header|Smalltalk}}==
{{works with|GNU Smalltalk}}
<
wholeContent: aPattern do: twoBlock [
self wholeContent: aPattern withLevel: 0 do: twoBlock.
Line 2,180 ⟶ 2,552:
]
]
].</
<
d := Directory name: '.'.
d wholeContent: '\.st$' do: [ :f :l |
0 to: l do: [ :i | (Character tab) display ].
f displayNl
].</
=={{header|Swift}}==
{{works with|Swift|3.0}}
<
let fileSystem = FileManager.default
Line 2,211 ⟶ 2,583:
}
}
}</
=={{header|Tcl}}==
{{works with|Tcl|8.5}}
<
package require fileutil
proc walkin {path cmd} {
Line 2,247 ⟶ 2,619:
}
}}}
</syntaxhighlight>
=={{header|TXR}}==
There is more than one way to do this in TXR. A recursive walk could be coded using <code>open-directory</code> and <code>getline</code>. Or FFI could be used to gain access to some platform-specific functions like Microsoft's <code>FindFirstFile</code> and so forth.
===Using <code>ftw</code>===
TXR wraps and exposes the POSIX <code>nftw</code> function, which is demonstrated here. This function encapsulates a tree walk, and uses callbacks to inform the program of visited filesystem tree nodes, and of error situations. We can use a <code>lambda</code> for the code walk, or wrap the invocation of <code>ftw</code> with a macro which hides the <code>lambda</code> syntax.
Line 2,257 ⟶ 2,630:
Here we use the <code>build</code> macro for procedural list building to gather all of the found paths into a list, which is implicitly returned. The callback is an explicit <code>lambda</code>:
<
(if (ends-with ".tl" path)
(add path)))))</
{{out}}
<
"./tests/sock-common.tl" "./tests/012/ifa.tl" "./tests/012/except.tl"
"./tests/012/fini.tl" "./tests/012/oop.tl" "./tests/012/circ.tl"
Line 2,280 ⟶ 2,653:
"./share/txr/stdlib/struct.tl" "./share/txr/stdlib/getput.tl"
"./share/txr/stdlib/path-test.tl" "./share/txr/stdlib/with-resources.tl"
"./share/txr/stdlib/yield.tl" "./share/txr/stdlib/conv.tl" "./share/txr/stdlib/termios.tl")</
For a regex pattern we can replace <code>(endswith ".tl" path)</code> with something like <code>(m$ path #/\.tl/)</code>.
Line 2,294 ⟶ 2,667:
A nice approach would be to capture a continuation in the callback, and then obtain the walk elements lazily; alas, capturing a continuation from a C library function's callback is not permitted, because the capture would span foreign stack frames.
===Using <code>glob*</code>===
TXR has a <code>glob*</code> function which, like <code>glob</code> is built on the POSIX C library function. <code>glob*</code> also provides Bash-style brace expansion, as well as the double star pattern, which we can use to find files recursively:
<syntaxhighlight lang="txrlisp">(glob* "**/*.c")</syntaxhighlight>
{{out}}
<syntaxhighlight lang="txrlisp">("args.c" "arith.c" "autoload.c" "buf.c" "cadr.c" "chksum.c" "chksums/crc32.c"
"chksums/md5.c" "chksums/sha1.c" "chksums/sha256.c" "combi.c"
"debug.c" "eval.c" "ffi.c" "filter.c" "ftw.c" "gc.c" "glob.c"
"gzio.c" "hash.c" "itypes.c" "lib.c" "linenoise/example.c" "linenoise/linenoise.c"
"match.c" "mpi/mpi.c" "mpi/mplogic.c" "parser.c" "protsym.c"
"psquare.c" "rand.c" "regex.c" "signal.c" "socket.c" "stream.c"
"struct.c" "strudel.c" "sysif.c" "syslog.c" "termios.c" "time.c"
"tree.c" "txr.c" "unwind.c" "utf8.c" "vm.c")</syntaxhighlight>
=={{header|UNIX Shell}}==
{{works with|Bourne Again SHell}}
The "find" command gives a one-line solution for simple patterns:
<
"find" can also be used to find files matching more complex patterns as illustrated in the section on [[#UnixPipes|Unix Pipes]] below.
Using "bash" version 4 or later, you can use "globstar" or "dotglob", depending on whether you want hidden directories to be searched:
<
# Warning: globstar excludes hidden directories.
# Turn on recursive globbing (in this script) or exit if the option is not supported:
Line 2,312 ⟶ 2,702:
echo "$f"
fi
done</
Here is a solution that does not use "find".
<
indent_print()
Line 2,356 ⟶ 2,746:
}
walk_tree "$1" "\.sh$"</
A simplified version that gives the same output:
<
walk_tree() {
Line 2,371 ⟶ 2,761:
}
walk_tree "$1" "\.sh$"</
=={{header|UnixPipes}}==
As illustrated [[#UNIX Shell|above]], the "find" command can be used with the -name option to match simple patterns. To find files matching more complex patterns, the results of "find" can be piped, e.g.
<
One way to run a command against each file that is found is to use "xargs", but if there is any possibility that a filename contains a space or tab character, then the following model should be used:
<
=={{header|Visual Basic .NET}}==
{{works with|Visual Basic .NET|9.0+}}
This uses the OS pattern matching
<
For Each file In directory.GetFiles(pattern)
Console.WriteLine(file.FullName)
Line 2,389 ⟶ 2,779:
walkTree(subDir, pattern)
Next
End Sub</
=={{header|Wren}}==
{{libheader|Wren-pattern}}
{{libheader|Wren-sort}}
<syntaxhighlight lang="wren">import "io" for Directory, File
import "./pattern" for Pattern
import "./sort" for Sort
var walk // recursive function
walk = Fn.new { |dir, pattern, found|
if (!Directory.exists(dir)) Fiber.abort("Directory %(dir) does not exist.")
var files = Directory.list(dir)
for (f in files) {
var path = dir + "/%(f)"
if (File.exists(path)) { // it's a file not a directory
if (pattern.isMatch(f)) found.add(f)
} else {
walk.call(path, pattern, found)
}
}
}
// get all C header files beginning with 'va' or 'vf'
var p = Pattern.new("v[a|f]+0^..h", Pattern.whole)
var found = []
walk.call("/usr/include", p, found)
Sort.quick(found)
for (f in found) System.print(f)</syntaxhighlight>
{{out}}
<pre>
valarray_after.h
valarray_array.h
valarray_before.h
valgrind.h
validate.h
values.h
vfio.h
vfio_ccw.h
vfs.h
</pre>
=={{header|zkl}}==
<
Lots of options, here I'm using the defaults: recurse, just file matches (not directory names) and return a bit bucket of ASCIIZ strings.
{{out}}
Line 2,408 ⟶ 2,839:
</pre>
globular will write to a object that has a write method or just call a method or function, which is nice for sending data to other threads (eg multi-threaded find/grep). To do the above example in one shot (without saving the results):
<
=={{header|Zsh}}==
Zsh has recursive globbing. The GLOB_DOTS option allows files beginning with a period to be matched.
<
print -l -- **/*.txt</
GLOB_DOTS can be set temporarily with the 'D' modifier.
<
{{omit from|ACL2|Very limited filesystem support.}}
|