6

For example I'm in my directory:

/home/myname

and then I want to CD into a different directory.

/home/pulsar/... 

Since I need to go pretty deep into the other directory, how can I go about this without having to type the whole line? I tried

cd */thedirectoryiwanttogointo

but that doesn't work. I have to type the whole line.

  • 3
    Consider using Tab Completion – eyoung100 Nov 7 '15 at 4:13
  • Could you edit with more details of what you're trying to do? Do you mean cd */foo to mean "find a directory called foo anywhere on the system and cd to it"? – Michael Homer Nov 7 '15 at 4:17
  • @ Michael Yes that's what I'm trying to do. Will * not work for that? – Goldname Nov 7 '15 at 4:18
  • @eyoung I have been using Tab Completion but with so many nested directories and similar names in this computer cluster, it hasn't been very useful. – Goldname Nov 7 '15 at 4:20
  • Well, what do you expect to happen if there's more than one directory with that name? How long do you expect it to take to find it? – Michael Homer Nov 7 '15 at 4:21
3

Probably your wildcard does not work because:

  • there were no matches for the wildcard from the location you gave, or
  • there was more than one match.

The usual approach (in a shell) to moving frequently among subdirectories is to use the CDPATH feature, as well as pushd and popd.

The CDPATH feature (perhaps first seen in tcsh) is a colon-separated list of directories. If the parent of your thedirectoryiwanttogointo name is reasonably unique, then you could add the parent to the list.

For further reading (your shell's manual page should be first):

pushd and popd are newer than CDPATH, but still dating from the mid-1990s. They allow you to save your current directory ("pushing" onto a stack) and restore it ("popping" from a stack) during their respective cd commands. For further reading:

Other people use shell aliases or symbolic links. Those are most useful when going to well-known locations.

2

You want wildcard expansion to find a path anywhere on the system. You can do that, if you specify the pattern correctly:

cd /**/thedirectoryiwanttogointo

will work in zsh and fish by default, in Bash if you first shopt -s globstar, in tcsh if you set globstar, in ksh93 if you set -o globstar, in yash if you set -o extended-glob.

This works because the wildcard is used within an absolute path starting with / instead of being relative to the current directory, and when you opt into using the ** pattern it expands to any number of subdirectories.

While this will work, it is likely to take an extremely long time. Your shell has to search your entire system for the matching file(s). You can cut that down by providing a longer prefix to trim out more of the search space:

cd /home/pulsar/**/thedirectoryiwanttogointo/

The further you drill down the less searching there will be to do. If the directory tree is fairly sparse, this won't take too long and is actually practical to use. The trailing / ensures that the expansion is only to a directory, which removes one variety of ambiguity that could occur.

If there's more than one match still, the result will depend on your shell. Bash and fish will switch to the alphabetically first match, ignoring the ambiguity. tcsh and yash will report an error. zsh and ksh will interpret it as an attempt to use one of their advanced directory-switching features and probably report an error.


If you're likely to use the same directory repeatedly, either putting the parent into CDPATH or creating a shell variable $FOO you can use in place of the long path is a better option. You can combine the shell variable with ** expansion to save more typing if you're using it often.

1

If you're always going to the same deep directory, one simple solution is to just create a symlink to it:

ln -s ~/foo/bar/baz/quux/etc/etc/etc/target ~/shortcut

If you've gone to the directory before, another solution is to search your command history for the name you want; press ctrl-R and the characters to search for. This is bash-specific, but I imagine most modern shells have a similar facility.

1

Assuming all the possible target directories are under /home and there's no newline characters in directory names, you might use this shell function:

cds() {
    cd "$(find /home -type d -name "$1" | head -n 1)"
}

$ cds thedirectoryiwanttogointo

Of course, depending on how many subdirectories and files are under /home and the ability for your OS to cache all the tree in memory or not, performance will vary significantly.

On GNU systems, you can speed it up and make it more reliable wrt newline characters in file names by using this syntax instead:

cds() {
    cd "$(find /home -type d -name "$1" -print -quit)"
}

That will stop searching as soon as the first match is found.

Note that the argument is taken as a pattern, so you can do:

cds 'foo*bar'

for instance to cd into the first directory (the order is not specified) whose name starts with foo and ends in bar.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.