Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time

Overview

filefind is a Lua module providing both highly efficient directory iteration and an expressive syntax for recursively globbing sets of files or directories from the disk in a single execution. The globbing functionality was inspired by Perforce's recursive wildcard syntax and implements JPSoft's TCC syntax for stepping up directories.

Example

    filefind = require 'filefind'

    for entry in filefind.glob('**') do
        print(entry.filename)
    end

Reference Manual

This is a reference of all of the filefind module's methods.

Module filefind

entryTable = filefind.attributes(filename)

Retrieves file or directory properties for one item.

for entry in filefind.glob(pattern) do

Begins a new iteration of files and/or directories using pattern as the glob wildcard. All glob syntax, described elsewhere, is available.

for entry in filefind.match(pattern) do

Begins a new iteration of files and directories using pattern as the wildcard. Simple access to the file system is used. The more powerful file globbing facilities are not available.

matches = filefind.pattern_match(pattern, string, caseSensitive = false, recursive = true) do

Tests string against pattern to determine a match. The syntax for pattern follows the wildcard globbing syntax described elsewhere in this document.

Pass true for caseSensitive to perform a search where case sensitivity matters. The default is false.

Pass true for recursive to perform a search where directory separators are tested and ** will work across directory separator boundaries. Pass false to use * to search across the entire string.

Time Conversion

lowTime, highTime = filefind.unix_time_to_FILETIME_UTC(unixTime)

Converts a Unix time_t to a Windows FILETIME adjusted to UTC. Returns the FILETIME as a two integers representing low time and high time.

entryTable = filefind.unix_time_to_FILETIME_UTC(unixTime)

Converts a Unix time_t to a Windows FILETIME adjusted to UTC. Returns the FILETIME as a two integers representing low time and high time.

entryTable = filefind.FILETIME_to_unix_time_UTC(filetime)

Converts a Windows FILETIME to Unix time_t adjusted to UTC. filetime may be two integers representing the low time and high time of the FILETIME structure or a string representing the low time and high time combined.

Returns the time_t.

entryTable = filefind.time_t_to_FILETIME(time_t)

Converts a Unix time_t to a Windows FILETIME. Returns the FILETIME as a two integers representing low time and high time.

entryTable = filefind.FILETIME_to_time_t(filetime)

Converts a Windows FILETIME to Unix time_t. filetime may be two integers representing the low time and high time of the FILETIME structure or a string representing the low time and high time combined.

Returns the time_t.

File entry information

entry.table - table - Returns a table with all of the properties below. Entry properties are usually looked up and returned on demand. Some may take extra time to compute.

entry.filename - string - The relative path from the filefind.match() starting directory.

entry.creation_time - number - The creation time of the file/directory in seconds starting from midnight (00:00:00), January 1, 1970.

entry.access_time - number - The last access time of the file/directory in seconds starting from midnight (00:00:00), January 1, 1970.

entry.write_time - number - The last write time of the file/directory in seconds starting from midnight (00:00:00), January 1, 1970.

entry.creation_FILETIME - table - The creation time of the file/directory in FILETIME format starting from midnight (00:00:00), January 1, 1970. Element 1 of the table is the low file time. Element 2 is the high file time.

entry.access_FILETIME - table - The last access time of the file/directory in FILETIME format starting from midnight (00:00:00), January 1, 1970. Element 1 of the table is the low file time. Element 2 is the high file time.

entry.write_FILETIME - table - The last write time of the file/directory in FILETIME format starting from midnight (00:00:00), January 1, 1970. Element 1 of the table is the low file time. Element 2 is the high file time.

entry.is_directory - boolean - true if the glob entry is a directory, false otherwise.

entry.is_link - boolean - true if the entry is a hard or symbolic link, false otherwise.

entry.is_readonly - boolean - true if the glob entry is read only, false otherwise.

entry.number_of_links - number - The number of files pointing to the hardlink blob, 0 if none.

entry.size - number - The size of the file.

Available Glob Syntax

<td width="150"><b>Wildcard</b></td>
<td width="450"><b>Description</b></td>
? Matches any single character of the file name or directory name.
* Matches 0 or more characters of the file name or directory name.
/ at end of pattern Any pattern with a closing slash will start a directory search, instead of the default file search.
** Search files recursively.
**/ Search directories recursively.

Some examples follow:

<td>Matches any file or directory starting with File and ending with a .txt extension.</td>
<td>Matches all files (recursive).</td>
<td><code>**/</code></td>
<td>Matches all directories (recursive).</td>
<td>Matches all *resource.h files recursively.
Expands to **/*resource.h.</td>
<td><code>BK**.h</code></td>
<td>Matches all *.h files in any directory starting with BK, recursively. Expands to BK*/**/*.h.</td>
<td>Recursively matches all directories under c:/Src/ that contain Grid. From the found directory, recursively matches directories until ABC/ is found. From there, the file <i>Readme.txt</i> is searched for recursively. </td>
Example Pattern Description
File.txt Matches a file or directory called File.txt.
File*.txt
File?.txt Matches any file or directory starting with File and containing one more character.
F??e*.txt Matches a file or directory starting with F, followed by any two characters, followed by e, then any number of characters up to the extension .txt.
File* Matches a file or directory starting with File and ending with or without an extension.
* Matches all files (non-recursive).
*/ Matches all directories (non-recursive).
A*/ Matches any directory starting with A (non-recursive).
**/*
** Shortened form of above. Matches all files (recursive). Internally, expands to **/*
**{filename chars} Matches {filename chars} recursively. Internally, expands to **/*{filename chars}.
{dirname chars}** Expands to {dirname chars}*/**.
{dirname chars}**{filename chars} Expands to {dirname chars}*/**/*{filename chars}.
**.h Matches all *.h files recursively. Expands to **/*.h.
**resource.h
BK** Matches all files in any directory starting with BK, recursively. Expands to BK*/**.
c:/Src/**/*.h Matches all *.h files recursively, starting at c:/Src/.
c:/Src/**/*Grid/ Recursively matches all directories under c:/Src/ that end with Grid.
c:/Src/**/*Grid*/ Recursively matches all directories under c:/Src/ that contain Grid.
c:/Src/**/*Grid*/**/ABC/**/Readme.txt

Finally, a couple flags are available. Flags are appended at the end of the pattern line. Each flag begins with an @ character. Spaces should not be inserted between flags unless they are intended as part of the string literal.

Flags and Other Expansions Description
@* Search files and directories recursively.
@-pattern Adds pattern to the file ignore list. Any file matching a pattern in the file ignore list is removed from the search.
@-pattern/ Adds pattern/ to the directory ignore list. Any directory matching a pattern in the directory ignore list is removed from the search.
@=pattern Adds pattern to the exclusive file list. Any file not matching a pattern in the exclusive file list is automatically removed from the search.
@=pattern/ Adds pattern/ to the exclusive directory list. Any directory not matching a pattern in the exclusive file list is automatically removed from the search.
More than two periods for going up parent directories. Similar to 4DOS, each period exceeding two periods goes up one additional parent directory. So, a 4 period path expands to ../../../.

Wildcards may appear anywhere in the pattern, including directories.

*/*/*/*.c

Note that . only matches files that have an extension. This is different than standard DOS behavior. Use * all by itself to match files, extension or not.

Recursive wildcards can be used anywhere:

c:/Dir1/**/A*/**/FileDirs*/**.mp3

This matches all directories under c:/Dir1/ that start with A. Under all of the directories that start with A, directories starting with FileDirs are matched recursively. Finally, all files ending with an mp3 extension are matched.

A few examples:

Example Pattern Description
Src/**/@-**/.git/@-**/.svn/ Recursively lists all directories under Src/, but directories called .git/ and .svn/ are filtered.
Src/**@=**.lua@=**/README Recursively lists all files under Src/ which match *.lua or README. All other files are ignored.
Src/**/@-**/.git/@-**/.svn/@=**.lua@=**/README Recursively lists all files under Src/ which match *.lua or README. The versions of those files that may exist in .git/ or .svn/ are ignored.
...../StartSearchHere/** Expands to: ../../../../StartSearchHere/**

License

The filefind module is licensed under the terms of the MIT and BSD licenses.

Credits

The filefind module glob source code was originally based on Matthias Wandel's MyGlob code, used in his Exif Jpeg camera setting parser and thumbnail remover application. It also expands upon the wildcmp() code written by Jack Handy.

For version 3.0, the MyGlob implementation was replaced with Ruby's faster implementation found in dir.c of the Ruby source code distribution.

Joshua Jensen wrote the rest of the filefind module.

History

  • Version 3.0 (23 Jan 2014)

    • Updated to Ruby's dir.c glob() implementation.
    • The @- and @= modifiers use a recursive pattern matching syntax.
  • Version 2.0 (9 Dec 2009)

    • Adds a revamped version of the old 'glob' module that handles iterators and has even better performance. Also adds support for the + modifier that will list both files and directories.
    • Changes the access functions to just member lookups for the resultant handle.
    • A number of bug fixes.
  • Version 1.0 (27 Aug 2002 - CodeProject article at http://www.codeproject.com/KB/files/fileglob.aspx)

    • Initial version.