Friday, October 14, 2016

Command line D utility - find files matching a pattern under a directory

By Vasudev Ram

Hi readers,

I wrote this utility in D recently, to find files matching a pattern (a wildcard) under a specified directory. Here is the program, find_files.d:
/************************************************************************
find_files.d
Author: Vasudev Ram
Compile with Digital Mars D compiler using the command:
dmd find_files.d
Usage: find_files dir patt
Finds files under directory 'dir' that match file wildcard 
pattern 'patt'.
The usual file wildcard patterns that an OS like Windows or 
Linux supports, such as *.txt, budget*.xls, my_files*, etc.,
are supported.
Copyright 2016 Vasudev Ram
Web site: https://vasudevram.github.io
Blog: http://jugad2.blogspot.com
Product updates: https://gumroad.com/vasudevram/follow
************************************************************************/

import std.stdio; 
import std.file;

string __version__ = "0.1";

void usage(string[] args) {
    debug {
        stderr.write("You gave the command: ");
        foreach(arg; args)
            stderr.write(arg, " ");
        stderr.writeln;
    }
    
    stderr.writeln(args[0], " (Find Files) v", __version__);
    stderr.writeln("Copyright 2016 Vasudev Ram" ~
    " - https://vasudevram.github.io");
    stderr.writeln("Usage: ", args[0], " dir pattern");
    stderr.writeln("Recursively find filenames, under directory 'dir', ");
    stderr.writeln("that match the literal or wildcard string 'pattern'.");
}

int main(string[] args) {

    // Check for and get correct command-line arguments.
    if (args.length != 3) {
        usage(args);
        return 1;
    }
    auto top_dir = args[1];
    if (!exists(top_dir) || !isDir(top_dir)) {
        stderr.writeln("The name ", top_dir, 
        " does not exist or is not a directory.");
        usage(args);
        return 1;
    }
    auto pattern = args[2];

    try {
        debug writeln(args[0], ": Finding files under directory: ", 
        top_dir, " that match pattern: ", pattern);
        foreach (de; dirEntries(top_dir, pattern, SpanMode.breadth)) {
            writeln(de.name);
        }
    }
    catch (Exception e) {
        stderr.writeln("Caught Exception: msg = ", e.msg);
        return 1;
    }
    return 0;
}
Compile command:
$ dmd -offf find_files.d
The -of flag is for "output file", and is used to specify the .EXE file to be created. The command creates ff.exe on Windows).

Compile command to create debug version (the statements prefixed 'debug' will also run):
$ dmd -debug -offf find_files.d

Here is the output from a few test runs of the find_files utility:

Run with no arguments - shows usage:
$ ff
ff (Find Files) v0.1
Copyright 2016 Vasudev Ram - https://vasudevram.github.io
Usage: ff dir pattern
Recursively find filenames, under directory 'dir',
that match the literal or wildcard string 'pattern'.
Run with one argument, a non-existent directory - shows usage, since number of arguments is invalid:
$ ff z
ff (Find Files) v0.1
Copyright 2016 Vasudev Ram - https://vasudevram.github.io
Usage: ff dir pattern
Recursively find filenames, under directory 'dir',
that match the literal or wildcard string 'pattern'.
Run with two argument, a non-existent directory and a file wildcard, * - gives message that the directory does not exist, and shows usage:
$ ff z *
The name z does not exist or is not a directory.
ff (Find Files) v0.1
Copyright 2016 Vasudev Ram - https://vasudevram.github.io
Usage: ff dir pattern
Recursively find filenames, under directory 'dir',
that match the literal or wildcard string 'pattern'.
Run with two argument, an existing directory and a file wildcard, * - gives the output of the files matching the wildcard under that directory (recursively):
$ ff . *
.\dir1
.\dir1\a.txt
.\dir1\dir11
.\dir1\dir11\b.txt
.\dir2
.\dir2\c.txt
.\dir2\dir21
.\dir2\dir21\d.txt
.\ff.exe
.\ff.obj
.\ffd.exe
.\find_files.d
.\find_files.d~
Note: It will find hidden files too, i.e. those with a H attribute, as shown by the DOS command DIR /A. If you find any issue with the utility, please describe it, with the error message, in the comments.

You can get the find_files utility (as source code) from here on my Gumroad product store:

https://gum.co/find_files

Compile the find_files.d program with the Digital Mars D compiler using the command:

dmd find_files.d

whhich will create the executable file find_files.exe.

Run:

find_files

to get help on the usage of the utility. The examples above in this post have more details.

- Enjoy.

Drawing of magnifying glass at top of post, by:

Yours truly.

- Vasudev Ram - Online Python training and consulting

Get updates on my software products / ebooks / courses.

Jump to posts: Python   DLang   xtopdf

Subscribe to my blog by email

My ActiveState recipes

Managed WordPress Hosting by FlyWheel



No comments: