Python LSF (ls + find) Program

Fri May 27 2016  [Updated: Wed Jan 10 2018]

Have you ever needed to search through your directories looking for files that match certain criteria? As a system administrator, I found myself doing this often and would usually use the unix find command to generate the list of matching files and then pipe that into an ls -l command to get the info I needed for each file. I found the syntax of the find command to be very unorthodox and hard to remember. The python script is an attempt to create a super-charged version of the basic ls command that adds options to control which files are included in the output.

Getting Started with lsf

Put the file somewhere in your $PATH. I also create a symbolic link in the same directory so that I only have to type lsf to execute it:

ln -s lsf    

Using the -h or --help option produces the built-in help documentation describing all the available options:

$ lsf -h
usage: lsf [-h] [-a DATETIME] [-A] [-c DATETIME] ...


The -f or --fields option allows you to specify exactly which pieces of information are printed out for each file. By default, the output fields are the same as ls gives you when using the -l option:

$ lsf

Directory .

-rw-r--r-- 1 root root        128 Sep 18  2014 0hourly
-rw-r--r-- 1 root root        108 Aug 26  2014 raid-check

Total of 2 files, 236 bytes

If you want the output to be more ls-like, you could use the -q option to get rid of the lines that show you what directory you’re listing and the summary line that gives the total number of files and bytes in those files. And if you wanted output like ls without the -l option (i.e. just show the filenames) you would set the fields to only the filename (-fn or --fields=n). If you wanted this to be your default output format, you can set these options in the LSF_OPTIONS environment variable:

LSF_OPTIONS="--quiet --fields=n"

Now we get:

$ lsf

Control over the output fields lets you do things like showing both the modified time and last accessed time for each file, which you can’t do with ls.

lsf --fields=mtime,atime,name

Most of the other options are used to determine which files are included in the output list. For example, to only show files smaller than 1 megabyte:

lsf -s 1m

Or only those greater than 2 gigabytes:

lsf --size=+2g

Or greater than 10 megs but less than 100 megs:

lsf --size=+10m --size=100m

The lsf utility supports regular expressions that can be matched against filenames, directory paths, or both. This command finds all files containing an uppercase letter in the name while searching recursively through all subdirectories:

lsf --recursive --name="[A-Z]"

while this one would find files with names containing only uppercase letters and underscores:

lsf --recursive --name="^[A-Z_]+$"

More Complex Criteria

As in the example above where we selected by file size, you can generally reverse the comparison by starting the option value with a plus sign. For example:

$ lsf --size=1g # show files smaller than 1 gigabyte
$ lsf --size=+1g # show files larger than 1 gigabyte
$ lsf --accessed=3d # files accessed in last 3 days
$ lsf -a +3d # last access was prior to 3 days ago

You can combine as many options for selecting files as you want. They will be AND-ed together, meaning that lsf will only list files that match ALL of the conditions you specified. The --filter option allows you to make your selections based on a python expression, which gives you unlimited flexibility.

$ lsf --filter="(size <= 10m) or (uid == 100)"

File Processing

You can have lsf perform a command on every matching file by using the -x or --execute option. You set the value to a command string with a pair of curly brackets used as a placeholder where the filepath of each file will be inserted. Use with caution! By default, lsf will show you the resulting command and ask for confirmation before it executes. If you're confident that no innocent files will be hurt in the process, you can put a plus sign at the beginning of the command to execute without confirmations.

$ lsf -R --size=+1g --execute="rm {}" /tmp # cautious
$ lsf -R --size=+1g --execute="+rm {}" /tmp # confident  

Downloading lsf

You can get the source code for lsf from its home on github.

Keywords: python,software,linux