<commit_before>---
layout: default
title: How to navigate directories faster with bash
---

# How to navigate directories faster with bash



*Changing directories* is an extremely frequent activity during my everyday work as a knowledge worker running calculations, analyzing data, and developing code from the terminal.  In fact, changing directories is the basic mode of operation to walk between different tasks, context, or work spaces.

When I first started  using the terminal the only command I knew was `cd` but throughout the years I noticed that there is a lot more under the hood of bash that significantly reduces the time needed to change directories. Below I share five tricks I use frequently to jump between directories. They not only help me to move faster but also reduces the cognitive load of remembering long subdirectories.

Furthermore, I use all tricks together for maximum efficiency and I hope they make you more productive, too.


* [Max Out cd](#max-out)
* [$CDPATH](#cdpath)
* [pushd](#pushd)
* [history](#history)
* [latest file](#lf)


<a id='max-out'></a>
## Max Out cd



This tip focuses solely on using all capabilities of the `cd` command.  The most common form of using `cd` is

    cd directory

where `directory` can be either a `./relative` or an `/absolute` path. Also quite well-known is that `..` is an alias for the directory above the current directory, `../..` the one above that and so on. Maybe less well-known is that `~` is an alias for one's home directory. However an even faster way to go there directly is to skip the `directory` argument and just use

    cd

Furthermore `-` is an alias for the previous directory. So `cd -` is like a back-button for `cd` that works for exactly one step in the history. Using `cd -` repeatedly toggles between two directories.

I also find it useful to alias `cd ..` like

    alias ..="cd .."

and there is no reason to stop there, so adding

    alias ..="cd .."
    alias ...="cd ../.."
    alias ....="cd ../../.."
    alias .....="cd ../../../.."
    alias ......="cd ../../../../.."
    alias .......="cd ../../../../../.."
    alias ........="cd ../../../../../../.."
    alias .........="cd ../../../../../../../.."
    alias ..........="cd ../../../../../../../../.."
    alias ...........="cd ../../../../../../../../../.."
    alias ............="cd ../../../../../../../../../../.."
    alias .............="cd ../../../../../../../../../../../.."

can bring you up many more directories by just adding dots (...) :-).


Another neat short hand is `!$` which is an alias for the last argument of the previous command. This can be handy if one creates a new directory and wants to change into it without typing the the directory again. So commands would be

    mkdir -p make/new/directory
    cd !$

and you are there.

[up](#top)

<a id='cdpath'></a>
## Configure $CDPATH to your workflow

The next tip is efficient use of the `CDPATH` variable. Almost everyone using a shell is familiar with the importance of the `PATH` variable. The `PATH` variable means that whenever one enters a `command` the shell will look up the directories listed in the `PATH`, search for executable files and then executes the first executable it finds named `command` in the order listed in `PATH`.

So there is a closely related variable named CDPATH which is the analog for `cd`. When you enter

    cd directory

`cd` will search all directories listed in `CDPATH` and jump to the first directory it finds in the order listed in `CDPATH`. The default setting is `CDPATH=.`, which means `cd` only searches the current working directory.  But there is no reason to stop where. My `~/.bashrc` contains export CDPATH=.:~:~/src:~/calculations:~/ssh_mounts

With this line I can always directly jump directly to any directory below the current directory, the home directory, a directory named `src` for software projects, a directory for `calculations`, and a directory named `ssh_mounts` that may link to other servers linked via the [sshfs](https://de.wikipedia.org/wiki/SSHFS) program.

This helps to keep directories for different types of activities apart while also allowing for quick changes between them. It is more powerful if one has only one `~/.bashrc` for all user accounts and synchronizes it using e.g. [git](https://git-scm.com/), and bash completion

    if [ -f /etc/bash_completion ]; then
      . /etc/bash_completion
    elif [ -f /opt/local/etc/profile.d/bash_completion.sh ]; then
      . /opt/local/etc/profile.d/bash_completion.sh
    fi


Another neat bash option is

    shopt -s cdspell

which automatically corrects small typos in directory names and jumps to the best guess of existing directories.
<commit_msg>Added complete -d cd to tip<commit_after>---
layout: default
title: How to navigate directories faster with bash
---

# How to navigate directories faster with bash



*Changing directories* is an extremely frequent activity during my everyday work as a knowledge worker running calculations, analyzing data, and developing code from the terminal.  In fact, changing directories is the basic mode of operation to walk between different tasks, context, or work spaces.

When I first started  using the terminal the only command I knew was `cd` but throughout the years I noticed that there is a lot more under the hood of bash that significantly reduces the time needed to change directories. Below I share five tricks I use frequently to jump between directories. They not only help me to move faster but also reduces the cognitive load of remembering long subdirectories.

Furthermore, I use all tricks together for maximum efficiency and I hope they make you more productive, too.


* [Max Out cd](#max-out)
* [$CDPATH](#cdpath)
* [pushd](#pushd)
* [history](#history)
* [latest file](#lf)


<a id='max-out'></a>
## Max Out cd



This tip focuses solely on using all capabilities of the `cd` command.  The most common form of using `cd` is

    cd directory

where `directory` can be either a `./relative` or an `/absolute` path. Also quite well-known is that `..` is an alias for the directory above the current directory, `../..` the one above that and so on. Maybe less well-known is that `~` is an alias for one's home directory. However an even faster way to go there directly is to skip the `directory` argument and just use

    cd

Furthermore `-` is an alias for the previous directory. So `cd -` is like a back-button for `cd` that works for exactly one step in the history. Using `cd -` repeatedly toggles between two directories.

I also find it useful to alias `cd ..` like

    alias ..="cd .."

and there is no reason to stop there, so adding

    alias ..="cd .."
    alias ...="cd ../.."
    alias ....="cd ../../.."
    alias .....="cd ../../../.."
    alias ......="cd ../../../../.."
    alias .......="cd ../../../../../.."
    alias ........="cd ../../../../../../.."
    alias .........="cd ../../../../../../../.."
    alias ..........="cd ../../../../../../../../.."
    alias ...........="cd ../../../../../../../../../.."
    alias ............="cd ../../../../../../../../../../.."
    alias .............="cd ../../../../../../../../../../../.."

can bring you up many more directories by just adding dots (...) :-).


Another neat short hand is `!$` which is an alias for the last argument of the previous command. This can be handy if one creates a new directory and wants to change into it without typing the the directory again. So commands would be

    mkdir -p make/new/directory
    cd !$

and you are there.

[up](#top)

<a id='cdpath'></a>
## Configure $CDPATH to your workflow

The next tip is efficient use of the `CDPATH` variable. Almost everyone using a shell is familiar with the importance of the `PATH` variable. The `PATH` variable means that whenever one enters a `command` the shell will look up the directories listed in the `PATH`, search for executable files and then executes the first executable it finds named `command` in the order listed in `PATH`.

So there is a closely related variable named CDPATH which is the analog for `cd`. When you enter

    cd directory

`cd` will search all directories listed in `CDPATH` and jump to the first directory it finds in the order listed in `CDPATH`. The default setting is `CDPATH=.`, which means `cd` only searches the current working directory.  But there is no reason to stop where. My `~/.bashrc` contains export CDPATH=.:~:~/src:~/calculations:~/ssh_mounts

With this line I can always directly jump directly to any directory below the current directory, the home directory, a directory named `src` for software projects, a directory for `calculations`, and a directory named `ssh_mounts` that may link to other servers linked via the [sshfs](https://de.wikipedia.org/wiki/SSHFS) program.

This helps to keep directories for different types of activities apart while also allowing for quick changes between them. It is more powerful if one has only one `~/.bashrc` for all user accounts and synchronizes it using e.g. [git](https://git-scm.com/), and bash completion

    if [ -f /etc/bash_completion ]; then
      . /etc/bash_completion
    elif [ -f /opt/local/etc/profile.d/bash_completion.sh ]; then
      . /opt/local/etc/profile.d/bash_completion.sh
    fi


Another neat bash option is

    shopt -s cdspell

which automatically corrects small typos in directory names and jumps to the best guess of existing directories. Or

    complete -d cd

which causes tab-completion after typing `cd` to only suggest directories.

{'fraction_non_alphanumeric': 0.1360259495657633, 'fraction_numerical': 0.0, 'mean_word_length': 2.7511773940345368, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6742785', 'n_tokens_mistral': 2586, 'n_tokens_neox': 2378, 'n_words': 1327}