Walk a directory/Non-recursively

From Rosetta Code
Revision as of 22:10, 27 January 2007 by rosettacode>Vcelier (Add Ada version)
Task
Walk a directory/Non-recursively
You are encouraged to solve this task according to the task description, using any language you may know.

Walk a given directory and print files matching a given pattern.

Note: Please be careful when running any code presented here.

Ada

Compiler: GCC 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;

C

Compiler: GCC 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(&reg, pattern, REG_EXTENDED | REG_NOSUB))
        return;
    if (!(d = opendir(dir)))
        return;
    while (entry = readdir(d))
        if (!regexec(&reg, entry->d_name, 0, NULL, 0))
            puts(entry->d_name);
    closedir(d);
}

int main()
{
    walker(".", ".\\.c$");
    return 0;
}

C#

Compiler: MSVS 2005

 foreach( string file in Directory.GetFiles( @"c:\temp", @"*.txt" ) )
   System.Console.WriteLine( file );

ColdFusion

This example display all files and directories in 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>

Haskell

Interpreter: GHCi 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$"

Java

Compiler: javac, JDK 1.4 and up

Done using no pattern. But with end string comparison which gave better results.

import java.io.File;
public class MainEntry {
    public static void main(String[] args) {
        walkin(new File("/home/user")); //Replace this with a suitable directory
    }
    
    /**
     * Recursive function to descent into the directory tree and find all the file 
     * that end with ".mp3"
     * @param dir A file object defining the top directory
     **/
    public static void walkin(File dir) {
        String pattern = ".mp3";
        
        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());
                    }
                }
            }
        }
    }
}

Perl

Interpreter: Perl

my @files = FindFiles('/home/user/music/', 'sql');
print "$_\n" for (@files);

sub FindFiles($ $){
  my $dir = shift;
  my $match = shift;

  opendir(DIR, $dir);
  my @files = grep(/$match/, readdir(DIR));
  closedir(DIR);

  return(@files);
}

PHP

Interpreter: PHP 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";
        }
    }
}

Python

Interpreter: Python 2.5

 import fnmatch
 import os
 
 rootPath = '/'    # Change to a suitable path for your OS
 pattern = '*.mp3' # Any string; Can include any UNIX shell-style wildcards
                   # Includes: *, ?, [seq], [!seq]
 for root, directories, files in os.walk(rootPath):
     for aFile in files:
         if fnmatch.fnmatch(aFile, pattern):
             print os.path.join(root, aFile)


Interpreter: Python 2.5 Libraries: Path Python module

 from path import path
 
 rootPath = '/'
 pattern = '*.mp3'
 
 d = path(rootPath)
 for f in d.walkfiles(pattern):
   print f

Ruby

Pattern matching using regular expressions

 #define a recursive function that will traverse the directory tree
 def printAndDescend(pattern)
   #we keep track of the directories, to be used in the second, recursive part of this function
   directories=[]
   Dir['*'].sort.each do |name|
     if File.file?(name) and name[pattern]
       puts(File.expand_path(name))
     elsif File.directory?(name)
       directories << name
     end
   end
   directories.each do |name|
     #don't descend into . or .. on linux
     Dir.chdir(name){printAndDescend(pattern)} if !Dir.pwd[File.expand_path(name)]
   end
 end
 #print all ruby files
 printAndDescend(/.+\.rb$/)

Or use the Find core Module

 require 'find'
 
 def find_and_print(path, pattern)
   Find.find(path) do |entry|
     if File.file?(entry) and entry[pattern]
       puts entry
     end
   end
 end
 
 # print all the ruby files
 find_and_print(".", /.+\.rb$/)