Walk a directory/Recursively: Difference between revisions

Content added Content deleted
m (→‎{{header|CoffeeScript}}: works with node.js)
m (use {{out}} template)
Line 1:
{{task|File System Operations}}[[Category:Recursion]]
[[Category:Recursion]]
 
Walk a given directory ''tree'' and print files matching a given pattern.
 
Line 7 ⟶ 5:
 
'''Note:''' Please be careful when running any code examples found here.
 
{{omit from|MUMPS|Maybe it could be done. But not with $ZF unless you wrote a OS level script and called that}}
=={{header|Ada}}==
<lang ada>with Ada.Directories; use Ada.Directories;
Line 65 ⟶ 63:
 
walk tree(".", match sort a68 and print)</lang>
{{out|Sample Output:output}}
<pre>
./Shell_sort_c.a68
Line 88 ⟶ 86:
=={{header|Batch File}}==
<lang dos>dir /a-d %1</lang>
 
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)}}
<lang dos>FOR /R C:\Windows\System32 %%F IN (*.DLL) DO ECHO "%%F"</lang>
 
This can be done from outside a batch file (entered directly at the command prompt) by changing the double percent signs (%%) to single percents (%):
<lang dos>FOR /R C:\Windows\System32 %F IN (*.DLL) DO ECHO "%F"</lang>
Line 234 ⟶ 229:
return 0;
}</lang>
 
==={{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}}
<lang c>#include <sys/types.h>
Line 323 ⟶ 316:
return 0;
}</lang>
 
=== [[Windows]] ===
{{libheader|Win32}}
Line 568 ⟶ 560:
=={{header|CoffeeScript}}==
{{works with|node.js}}
<lang coffeescript>fs = require 'fs'
fs = require 'fs'
 
walk = (dir, f_match, f_visit) ->
Line 585 ⟶ 576:
matcher = (fn) -> fn.match /\.coffee/
action = console.log
walk dir, matcher, action</lang>
</lang>
 
=={{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.
 
<lang lisp>(defun mapc-directory-tree (fn directory)
(dolist (entry (cl-fad:list-directory directory))
Line 612 ⟶ 599:
 
=={{header|C sharp|C#}}==
<lang csharp>using System.IO;
using System.IO;
 
namespace ConsoleApplication1
Line 663 ⟶ 649:
=={{header|C++}}==
{{libheader|boost}}
 
<lang cpp>#include "boost/filesystem.hpp"
#include "boost/regex.hpp"
Line 696 ⟶ 681:
 
=={{header|D}}==
module std.file provides different walk directory functions (listdir).<br>
 
This one recursively walks the directory, which can either match by regular expression or unix shell style pattern.
<lang d>import std.stdio;
Line 745 ⟶ 731:
listdir(path, &matchNPrint) ;
}</lang>
 
=={{header|E}}==
 
<lang e>def walkTree(directory, pattern) {
for name => file in directory {
Line 759 ⟶ 744:
}
}</lang>
{{out|Example}}
 
Example:
 
<lang e>? walkTree(<file:/usr/share/man>, "rmdir")
/usr/share/man/man1/rmdir.1
Line 768 ⟶ 751:
=={{header|F_Sharp|F#}}==
This code is tail-recursive and lazy.
<lang fsharp>open System.IO
open System.IO
 
let rec getAllFiles dir pattern =
Line 777 ⟶ 759:
 
getAllFiles "c:\\temp" "*.xml"
|> Seq.iter (printfn "%s")</lang>
</lang>
 
=={{header|Factor}}==
Line 789 ⟶ 770:
=={{header|Forth}}==
{{works with|gforth|0.6.2}}
 
''Todo: track the full path and print it on matching files.''
 
<lang forth>defer ls-filter
 
Line 875 ⟶ 854:
 
=={{header|Groovy}}==
 
Print all text files in the current directory tree
<lang groovy>new File('.').eachFileRecurse {
Line 882 ⟶ 860:
 
=={{header|GUISS}}==
 
Here we list all files that match the pattern m*.txt in "My Documents" and all of its subfolders:
 
<lang guiss>Start,Find,Files and Folders,Dropdown: Look in>My Documents,
Inputbox: filename>m*.txt,Button:Search</lang>
 
=={{header|Haskell}}==
 
<lang haskell>import System.Environment
import System.Directory
Line 903 ⟶ 878:
 
=={{header|IDL}}==
 
<lang idl>result = file_search( directory, '*.txt', count=cc )</lang>
 
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>
 
== Icon and Unicon ==
==={{header|Icon}}===
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}}===
<lang Unicon>procedure main()
Line 930 ⟶ 903:
 
=={{header|J}}==
 
<lang j>require 'dir'
>{."1 dirtree '*.html'</lang>
Line 939 ⟶ 911:
 
=={{header|Java}}==
 
{{works with|Java|1.4+}}
Done using no pattern. But with end string comparison which gave better results.
<lang java>import java.io.File;
 
<lang java>import java.io.File;
public class MainEntry {
public static void main(String[] args) {
Line 958 ⟶ 929:
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i=0; i<listFile.length; i++) {
if (listFile[i].isDirectory()) {
walkin(listFile[i]);
} else {
if (listFile[i].getName().endsWith(pattern)) {
System.out.println(listFile[i].getPath());
}
Line 977 ⟶ 948:
import java.nio.file.attribute.BasicFileAttributes;
public class WalkTree {
public static void main(String[] args) throws IOException {
Path start = FileSystems.getDefault().getPath("/path/to/file");
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
if (file.toString().endsWith(".mp3")) {
System.out.println(file);
}
Line 1,027 ⟶ 998:
 
=={{header|Mathematica}}==
The built-in function <code>FileNames</code> does exactly this:
:<lang Mathematicacode>FileNames[]</code> lists all files in the current working directory.
:<code>FileNames[form]</code> lists all files in the current working directory whose names match the string pattern form.
:<code>FileNames[{form1,form2,...}]</code> lists all files whose names match any of the form_i.
:<code>FileNames[forms,{dir1,dir2,...}]</code> lists files with names matching forms in any of the directories dir_i.
:<code>FileNames[forms,dirs,n]</code> includes files that are in subdirectories up to n levels down.</lang>
Examples (find all files in current directory, find all png files in root directory, find all files on the hard drive):
<lang Mathematica>FileNames["*"]
Line 1,130 ⟶ 1,101:
=={{header|Perl 6}}==
Uses File::Find from [http://github.com/tadzik/perl6-File-Tools File-Tools]
 
<lang perl6>use File::Find;
 
Line 1,149 ⟶ 1,119:
}
findFiles('./foo', '/\.bar$/');</lang>
 
This implementation uses Perl compatible regular expressions to match the whole path of the file
 
Line 1,170 ⟶ 1,139:
Released as open license for any use.
*/
if ($_SERVER['argc'] < 3) {
printf(
"\n" .
"Usage: %s (path) (search) [stop]\n" .
" path the path to search\n" .
" search the filename to search for\n" .
" stop stop when file found, default 1\n" .
"\n"
, $_SERVER['argv'][0]);
exit(1);
}
 
$path = $_SERVER['argv'][1];
$search = $_SERVER['argv'][2];
if ($_SERVER['argc'] > 3)
$stop = $_SERVER['argv'][3] == 1;
else $stop = true;
 
/* get the absolute path and ensure it has a trailing slash */
$path = realpath($path);
if (substr($path, -1) !== DIRECTORY_SEPARATOR)
$path .= DIRECTORY_SEPARATOR;
 
$queue = array($path => 1);
$done = array();
$index = 0;
while(!empty($queue)) {
/* get one element from the queue */
foreach($queue as $path => $unused) {
unset($queue[$path]);
$done[$path] = null;
break;
}
unset($unused);
 
$dh = @opendir($path);
if (!$dh) continue;
while(($filename = readdir($dh)) !== false) {
/* dont recurse back up levels */
if ($filename == '.' || $filename == '..')
continue;
 
/* check if the filename matches the search term */
if ($filename == $search) {
echo "$path$filename\n";
if ($stop)
break 2;
}
 
/* get the full path */
$filename = $path . $filename;
 
/* resolve symlinks to their real path */
if (is_link($filename))
$filename = realpath($filename);
 
/* queue directories for later search */
if (is_dir($filename)) {
/* ensure the path has a trailing slash */
if (substr($filename, -1) !== DIRECTORY_SEPARATOR)
$filename .= DIRECTORY_SEPARATOR;
 
/* check if we have already queued this path, or have done it */
if (array_key_exists($filename, $queue) || array_key_exists($filename, $done))
continue;
 
/* queue the file */
$queue[$filename] = null;
}
}
closedir($dh);
}
closedir($dh);
</lang>
}</lang>
 
=={{header|PicoLisp}}==
Line 1,254 ⟶ 1,222:
((match '`(chop "s@.l") (chop F)) # Matches 's*.l'?
(println Path) ) ) ) ) ) ) # Yes: Print it</lang>
{{out}}
Output:
<pre>"./src64/sym.l"
"./src64/subr.l"
Line 1,260 ⟶ 1,228:
 
=={{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).
 
Built-in procedure sys_file_match searches directories or directory
trees using shell-like patterns (three dots indicate search for
subdirectory tree).
<lang pop11>lvars repp, fil;
;;; create path repeater
Line 1,318 ⟶ 1,283:
{{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.
 
<lang python>import fnmatch
import os
Line 1,330 ⟶ 1,293:
for filename in fnmatch.filter(files, pattern):
print( os.path.join(root, filename))</lang>
 
{{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:
 
<lang python>from fnmatch import fnmatch
import os, os.path
Line 1,345 ⟶ 1,305:
 
os.path.walk('/', print_fnmatches, '*.mp3')</lang>
 
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.
 
Of course the function being passed down through ''os.path.walk()'' can also be an instance of an object which maintains it's own data collections. Any matching criteria can be set as attributes of that object in advance and methods of that object can be called upon for later processing as well. That would the an object oriented approach which would obviate the need for the "arguments" to be passed through ''os.path.walk()'' at all.
 
{{works with|Python|2.5}}
 
{{libheader|Path}}
(''Note:'' This uses a non-standard replacement to the '''os.path''' module)
 
<lang python>from path import path
 
Line 1,368 ⟶ 1,324:
 
=={{header|REALbasic}}==
<lang vb>Sub printFiles(parentDir As FolderItem, pattern As String)
<lang vb>
Sub printFiles(parentDir As FolderItem, pattern As String)
For i As Integer = 1 To parentDir.Count
If parentDir.Item(i).Directory Then
Line 1,381 ⟶ 1,336:
End If
Next
End Sub</lang>
</lang>
 
Accepts a FolderItem object and a Regex pattern as a string:
<lang vb>
Line 1,392 ⟶ 1,345:
=={{header|Ruby}}==
Using the Find core Module
<lang ruby>require 'find'
 
Line 1,398 ⟶ 1,350:
# print file and path to screen if filename ends in ".mp3"
puts f if f.match(/\.mp3\Z/)
end</lang>
</lang>
 
=={{header|Scala}}==
Line 1,405 ⟶ 1,356:
@SEE: http://stackoverflow.com/questions/3444748/porting-new-iterable-code-from-scala-2-7-7-to-2-8
 
This is not implemented in the Scala library. Here is a possible solution, building on [[Java]] class ''<code>java.io.File</code>'' and on scala language and library iteration facilities:
 
<lang scala>package io.utils
 
Line 1,429 ⟶ 1,379:
implicit def toRichFile(file: File) = new RichFile(file)
}</lang>
 
Class ''RichFile'' gets a ''java.io.File'' in constructor. Its two methods return ''Iterable''s on items of type File. ''children'' allow iterations on the direct children (empty if file is not a directory). ''andTree'' contains a file and all files below, as a concatenation (''++'') of a sequence which contains only a file (''Seq.single'') and actual descendants. The method ''flatMap'' in Iterable takes a function argument which associates each item (''child'') to another Iterable (''andTree'' called recursively on that child) and returns the concatenation of those iterables.
 
Line 1,450 ⟶ 1,399:
=={{header|Scheme}}==
Varies slightly depending on the implementation of scheme.
 
{{works with|Chicken Scheme}}
<lang scheme>(use posix)
(use posix)
(use files)
(use srfi-13)
Line 1,468 ⟶ 1,415:
(FN MYPATH) )))) (directory PATH #t) ))
 
(walk (lambda (X) (cond ((string-suffix? ".scm" X) (display X)(newline) ))) "/home/user/")</lang>
</lang>
 
See also: '''(find-files ...)''' function in the '''posix''' module.
 
{{works with|Gauche}}
<lang scheme>(use file.util)
(use file.util)
(use srfi-13)
 
Line 1,488 ⟶ 1,431:
(FN MYPATH) )))) (directory-list PATH :add-path? #t :children? #t ) ))
 
(walk (lambda (X) (cond ((string-suffix? ".scm" X) (display X)(newline) ))) "/home/user/")</lang>
</lang>
See also: '''(find-file-in-paths ...)''' function in the '''file.util''' module.
 
{{works with|PLT Scheme}}
<lang scheme>#lang scheme
#lang scheme
 
(require srfi/13)
Line 1,509 ⟶ 1,449:
(FN MYPATH) )))) (directory-list PATH)))
 
(walk (lambda (X) (cond ((string-suffix? ".scm" (path->string X)) (display X)(newline) ))) "/home/user/")</lang>
</lang>
See also: '''(find-files ...)''' function in the '''file''' module.
{{out|Sample output}}
 
<pre>
Sample output:
<lang scheme>
/home/user/one.scm
/home/user/lang/two.scm
[...]
</langpre>
 
=={{header|Smalltalk}}==
Line 1,572 ⟶ 1,510:
=={{header|Visual Basic .NET}}==
{{works with|Visual Basic .NET|9.0+}}
 
This uses the OS pattern matching
 
<lang vbnet>Sub walkTree(ByVal directory As IO.DirectoryInfo, ByVal pattern As String)
For Each file In directory.GetFiles(pattern)
Line 1,586 ⟶ 1,522:
=={{header|UNIX Shell}}==
{{works with|Bourne Again SHell}}
 
The "find" command gives a one-line solution for simple patterns:
 
<lang bash>find . -name '*.txt' -type f </lang>
 
"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:
 
<lang bash>#! /bin/bash
# Warning: globstar excludes hidden directories.
Line 1,605 ⟶ 1,537:
echo "$f"
fi
done</lang>
 
</lang>
 
 
Here is a solution that does not use "find".
 
<lang bash>#! /bin/bash
 
Line 1,655 ⟶ 1,582:
 
walk_tree "$1" "\.sh$"</lang>
 
A simplified version that gives the same output:
 
<lang bash>#! /usr/bin/env bash
Line 1,674 ⟶ 1,599:
 
=={{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.
 
<lang bash>find . -type f | egrep '\.txt$|\.TXT$'</lang>
 
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:
 
<lang bash> find . -type f -name "*.txt" -print0 | xargs -0 fgrep sometext</lang>
 
Line 1,692 ⟶ 1,613:
{{omit from|Befunge}} <!-- No filesystem support -->
{{omit from|M4}}
{{omit from|MUMPS|Maybe it could be done. But not with $ZF unless you wrote a OS level script and called that}}
{{omit from|PARI/GP}}
{{omit from|Retro}}