Quick Tour

As Commandline Tool

Once you install FsQuass, it can work as command line tool. It’s almost like GNU find, except that it only searches and does not try to be a Swiss knife. There are no options in it:

$ fsquass '/home/*'
/home/siberiano
/home/guest
note:It’s better to quote the arguments since Bash may try to convert masks (*, .) for you.

If you need to do something with the found files, use xargs:

$ fsquass '/home .bashrc' | xargs cat

This prints the contents of all .bashrc files Descendants of user folders. As a quick tip on xargs, to pass file path in the middle of a command, use curly braces:

$ fsquass '/home .bashrc' | xargs -I '{}' ln -S {} /tmp

To each found .bashrc this will make a symlink in /tmp.

As a Python Module

The Fs class (stands for files set), like jQuery, searches by string and also inherits the API of set class with all set operations: union, intersection, add, remove, etc.

from fsquass import Fs
Fs('/home .bashrc') - Fs('~/.bashrc')  # similar to jQuery.not()

File sets are iterable and consist of File or Dir instances. They also can generate strings:

for project in Fs('~/projects/*'):
        print project

for path in Fs('~/projects/*'):  # a generator of string paths
        print path

Syntax

The syntax is essentially Unix filename patterns + some powerful extensions. Patterns work via fnmatch module. The special characters used in shell-style wildcards are: *, ? (any single character), [abc] (a, b or c), [!abc] anything but them. Some simple examples:

folder/folder/file.py[co]
folder/*/*.txt
/etc/hosts
/var/log/*.log
./file
file
../another_folder/file

The two latter examples are the same.

But here come some extensions: you can go a level up from a file:

fsquass/setup.py/..

This expression will evaluate to fsquass, but only if setup.py is present. This is useful if you need folders to contain specific children.

Descendants

It works like in CSS:

~ *.py

will search for *.py anywhere in the home folder, at any folders depth.

attention:This kind of search is expensive since it makes the program go through all the directory tree down from ~. Make such searches as narrow as possible if you can: */projects/django *.py.

You can make several such searches:

~/projects templates *.haml

Scans projects folder for templates, then scans each of those for *.haml.

The second part of descendant can be multi-level:

~/projects templates/*.haml

Use backslash to write a space in a name. Use double backslash if you need to escape the backslash itself:

~/project\ description/*

Yet there is no syntax for the opposite search, for random number of levels upwards.

Pseudo-Classes

Similar to those in CSS, they are written in the end or instead of a pattern, and either filter filesystem objects by type, or modify the pattern’s properties:

Pseudo-Class Meaning
:file object is a file
:dir object is a directory
:ignorecase makes search case-insensitive

Examples:

~/.*:dir
~/*:file
/home/:dir
/:dir
~/Pictures *.jpg:ignorecase

Sub-Patterns

In Unix shell, you can do this: mkdir project/{apps,templates,static}. The same works in fsquass. Between slashes, you can use curly braces to write multiple options:

/home/{siberiano,guest}/.bashrc
~/Pictures {*.jpeg:ignorecase,*.jpg:ignorecase}
note:Pseudo-classes must be inside the curly braces.

Multiple Patterns

If you need to find objects with completely different paths or patterns, write multiple expressions separated with a colon:

/etc/hosts;~/.my_hosts;~/test.txt

Put a backslash to a colon if it’s a part of a name:

strange\;name1;strange\;name2

Set Operations

Fs inherits from set and suspports all the set methods.

Fs('./*.py') | Fs('./*.pyc')  # union
Fs('. {*.rst,*.txt}') - Fs('./build *.txt')  # not
Fs('*.py') & Fs('__*__.py')  # intersection
Fs('*.py') ^ Fs('__*__.py')  # xor (union not intersection)

filter is just like interection, but is faster since it doesn’t search files on disk.

Fs('*.py').filter('__*__.py')

Traversing

Having one set of files you can generate another set relative of it:

# find Python scripts and then their parent folders that start with 'django'
django_projects = Fs('~/projcets *.py').parents('django*')

# inside those find __init__.py at top level
django_projects.children('__init__.py')

# or at any depth
django_projects.find('. __init__.py')

# find doc roots inside them, by relative path (no recursive search)
django_projects.find('docs/source/index.*')

django_projects.siblings()

Files Manipulation

Currently Fs supports

Project Versions

Table Of Contents

Previous topic

FsQuass, filesystem query and traversing

Next topic

fsquass Package

This Page