sd -- a drop-in replacement for `cd'

man page
Login

Below follows a transcript of the sd man page. See also the quistart guide.

NAME

sd - switch between directories using a dynamic directory stack

SYNOPSIS

sd [pattern pathname -]

sdirs [ -hmpfsicw ] [ -e num ] [ -l num ] [ -d pattern ] [pattern]

DESCRIPTION

The sd utility consists of a set of ksh functions enabling rapid navigation between recently visited directories. sd keeps track of all recent cd activities with the help of a logfile. This logfile is analyzed to generate a "frecency" distribution (combining frequency and recency) of the visits to different directories. The directory stack can be queried by further sd commands using pattern matching. A sliding window (containing a limited number of trailing entries from the logfile) is used. This leads to a dynamically changing stack which is updated after each sd action. While the logfile is shared by all running shells, the directory stack is not. Therefore, modifications of the logfile (and stack) by sd actions in one shell do not immediately affect the stack in another already running shell. sdirs -f can be used to enforce an update (rescan of the logfile). sdirs -w can be used to enforce an update of the logfile prior to termination of the presently running shell.

Some care is taken to maintain compatibility with bash and zsh. sd can be used in combination with tcsh, too, through the auxiliary ksh scripts sdcmd and sdirs. However, functionality is somewhat restricted in this case.

In all shells, interaction with sd proceeds solely via sd and sdirs.

USAGE

After correct setup sd can be used as a replacement for cd. sd takes one or more arguments that together define a string pattern (possibly containing blanks) which is first tried as a pathname. The special cases 'sd' and 'sd -' work as expected. If pathname interpretation fails, pattern is used for a lookup in the last sdlines directories visited (not counting your home directory). In this case pattern can be any valid regular expression. Characters special to the shell might need quoting and so do characters with special meaning to regex matching. Thus a lookup of a verbatim a.b requires the pattern a\\.b in order to get the quoting through.

The search is performed top-down starting at the most relevant directory. The working directory is changed to the first match found. If this match is not the correct one (and presuming there actually are multiple matches), repeatedly executing the same sd command again (typically by recalling it from the shell history) will cycle through all matches thus allowing to quickly reach the second (or third, etc.) match. Alternatively, the search pattern might be refined. Frequently, trailing substrings from the full pathname, notably the basename, work fine. It is also possible to switch between directories with 'sd =rank' where rank is the rank index displayed by sdirs. 'sd =' is equivalent to 'sd =1'. Quoting of the = might be necessary with older versions of tcsh and with zsh.

If sdselect=0, sdirs lists the directory stack in the four column format frecency frequency rank directory_name sorted top-down according to "frecency", i.e. taking into account frequency and recency of directory visits according to current value of sdpower. Specifying a pattern as argument restricts the display to matching entries. If sdselect=1, sdirs uses a three column format rank index directory_name and queries for the index value of the desired directory and than switches to that directory.

sdirs also serves as user interface for performing other tasks according to chosen option as detailed below.

OPTIONS

sdirs accepts these options:

-e
Set the exponent sdpower of the power law used for time weighting the logfile entries when computing the stack. Fractional values are allowed. The current value is 3. A value of 0 eliminates time weighting (stack sorted by frequency of visits). A sufficiently large value (e.g. 1000) enforces stack sorting by most recent visits.

-h
Show short usage note.

-m
Show manpage.

-p
If specified before -m, convert manpage to postscript and send to stdout.

-f
Forces a refresh of the directory stack. This might be helpful if sdlines or sdpower are modified interactively or if several shell incarnations are running in parallel.

-s
Displays the elements in the directory stack alphabetically instead of according to search order. Might be helpful for locating some ill-remembered pathname to find out its rank for a sd =rank command.

-i
Show status info for logfile and stack.

-c
Clean up logfile: remove stale entries no longer pointing to an existing directory and update the directory stack.

-w
write updated list of visited directories to logfile. Happens automatically when the shell terminates.

-l num
Change the number of recently visited directories considered when constructing the directory stack. As a special case, when the provided argument is zero or non-numeric, the complete currently available logfile content is used (so the easiest call to achieve this would be sdirs -ll).

-d pattern
Delete all entries matching the pattern from the logfile (deletion is performed only after a final confirmation by the user) and update the directory stack.

Options -e and -l are not available when used with tcsh. You have to modify the corresponding environment variables directly (see section Setup for tcsh below).

HANDLING OF NON-MATCHING PATTERNS

Whether a cd pattern command fails, i.e. whether pattern does not match any entry in the current directory stack, partly depends on the chosen value of sdlines (which might be modified in the corresponding resource file or interactively via dirs -l num).

As an attempt to improve handling of such initially failing cd actions, sd implements the following strategy (also covering the case of "stale" entries, i.e. entries pointing to a directory that has been deleted in the meantime):

  1. If cd pattern fails, first try to find another matching entry further down on the stack. If this fails too, temporarily increase sdlines to the total number of entries in the logfile (usually several 1000).

  2. Recreate the stack (which then contains all directories found in the logfile) and try again to find a matching entry (skipping over stale entries).

  3. Reset sdlines and recreate the stack.

In this way the chance of complete failure is distinctly reduced but it is of course not guaranteed that the top-most "hit" on the extended stack is the desired one. For this reason, by default a list of all hits on the extended stack is displayed, too, in order to enable the user to refine the search pattern if need be. To avoid this output define this shell variable: sdsilent=1.

SHELL VARIABLES

There are a few user-settable shell or environment variables recognized by sd. Regarding meaning of sdmax and sdlines see INITIAL SETUP section. sdlines can be changed with dirs -l num. sdpower can be changed with dirs -e num.

INITIAL SETUP

Setup for ksh, bash, and zsh

1. Put the file sd.ksh in a directory on the search path.

2. Insert a source sd.ksh command at or near the top of your startup file. The source command can be preceded by assignments to the variables sdmax and sdlines. sdlines defines the number of previous cd actions which are analyzed by sd. sdmax is the maximum number of cd actions logged in the file ~/.sd/dirv. If this limit is reached the file is pruned to the sdmax*9/10 or sdlines most recent cd actions, whichever is larger. The current values are sdmax=8192 and sdlines=512. sdlines can be modified interactively at any time to alter the "time window" accessible via the stack.

If a cd function is not already existing at the time sd.ksh is sourced, sd defines it as

function cd {
   sd "$@"
}

which effectively aliases cd to sd. Using "$@" (rather than $* or $*) is the right thing to do here considering the possibility of multiple blanks in (quoted) patterns or an IFS=$'\n'. If you have your own cd function you might want to include the above sd call in that function. sd furthermore defines

alias dirs=sdirs
alias ds=sdirs

The former alias overrides the dirs builtin in bash and zsh. You probably don't want to use the builtin in parallel to sd anyway, but if you need it simply issue

unalias dirs

after sourcing sd.ksh.

Bash users

Note that sd sets the non-standard option shopt -s extglob which activates ksh like extended shell glob patterns. If this interferes with your setup, don't use sd.

zsh users

Note that sd sets the non-standard options set -o KSH_GLOB (which activates ksh like extended shell glob patterns) and set -o POSIX_BUILTINS (which enables the command builtin to execute shell builtins). If this interferes with your setup, don't use sd.

Setup for tcsh

1. Put files sd.ksh, sdcmd, and sdirs in a directory on the search path. Make the last two of these executable.

2. Add the following lines verbatim (including the quotes) to your startup file:

alias cd   'eval "`sdcmd \\!*`"'
alias dirs 'sdirs'
alias ds   'sdirs'

Note that the second alias overwrites the dirs builtin of tcsh. If you don't like this, omit this alias definition.

To modify variables relevant to sd, you have to export them to the environment of your shell with setenv.