Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I would find it very convenient to be able to use cd with a file argument.

cd myDirectory/anyname.anyExtension would be equivalent to cd myDirectory/

What would be the best alias or function to achieve this behavior ?

EDIT: Sorry I didn't mention it in the 1st place: I use zsh

share|improve this question
add comment

4 Answers

up vote 2 down vote accepted

In zsh, I often do:

cd /path/to/somefile(:h)

(h for head).

If somefile is a symlink, you can also do:

cd somefile(:A:h)

To get to the directory where the target of the symlink may be found.


The zsh equivalent of Chris' now bash-only solution would be:

cd() {
  [[ ! -e $argv[-1] ]] || [[ -d $argv[-1] ]] || argv[-1]=${argv[-1]%/*}
  builtin cd "$@"
}

In zsh, you can also redefine what "words" Ctrl-W removes.

In zsh, "words" in the context of the word-based motion/transpose/delete widgets are sequences of alnums plus the characters in the $WORDCHARS variable which by default includes /.

You could remove / from $WORDCHARS so that Ctrl-W only deletes one path component:

WORDCHARS=${WORDCHARS/\/}

Another useful extension is the select-word-style widget which you can use to interactively choose between different word styles.

autoload select-word-style
zle -N select-word-style
bindkey '\ew' select-word-style

Then pressing Alt-W allows you to choose between different word styles.

$ cd /blah/blih<Alt-W>
Word styles (hit return for more detail):
(b)ash (n)ormal (s)hell (w)hitespace (d)efault (q)uit
(B), (N), (S), (W) as above with subword matching
?
share|improve this answer
    
Interesting. (I use zsh too). –  Sebastien May 18 '13 at 9:17
    
Very interesting edit on the power of zsh and word styles. Thank you also for the zsh command. It does the job perfectly. –  Sebastien May 22 '13 at 13:33
add comment

I assume you still want to retain the original functionality if you input a directory, and you are using bash.

cd() {
    local file="${!#}"

    if (( "$#" )) && ! [[ -d "$file" ]]; then
        builtin cd "${@:1:($#-1)}" "${file%/*}"
    else
        builtin cd "$@"
    fi
}

If you are never going to use cd's options (-P, etc), then this will also suffice:

cd() { 
    if [ -d "$1" ] || [ -z "$1" ]; then
        builtin cd "$@"
    else
        builtin cd "${1%/*}"
    fi
}
share|improve this answer
4  
if you change the function name to cd make sure to add builtin in front of the cd calls –  Ulrich Dangel May 17 '13 at 17:22
    
@Chris: You assumed right ;) Thanks for this ready to use function –  Sebastien May 18 '13 at 9:21
    
The version that preserves cd options does not work with zsh. The simpler one works fine with zsh, BUT cd is no longer equivalent as cd ~ :/ –  Sebastien May 22 '13 at 13:24
    
@Sebastien Try now, I think that should fix that. –  Chris Down May 22 '13 at 14:20
    
@Chris, indeed adding a check on [ -z "$1" ] was sufficient. I have accepted Stephane's answer to give it more visibility, as it seems to be the best solution for zsh. –  Sebastien May 23 '13 at 8:18
add comment

You could use dirname to strip the filename from the path, e.g.

mycd() { cd "$(dirname "$1")"; }

See man dirname.

share|improve this answer
2  
Note that if you input a directory, this will change to the directory above that directory, which may not be desired (it's unclear from the question whether this is desired or not). –  Chris Down May 17 '13 at 18:08
1  
@ChrisDown True, but I left that as an exercise to the reader and your answer shows how to deal with it. –  Adrian Frühwirth May 17 '13 at 18:10
    
@AdrianFrühwirth An exercise! Hah! –  Herman Torjussen May 17 '13 at 18:24
add comment

If you add this to your .profile, then load it (source ~/.profile or log out and log in again), then mycd [file or directory] will take you to the right directory:

mycd() { if [ -d "$1" ]; then cd "$1"; else cd "$( dirname "$1" )"; fi ; }

If you name it cd, then strange things will happen.

share|improve this answer
1  
This will break if the directory name contains whitespace, and you need a closing semicolon to terminate the command group. Edited it for you, hope you don't mind. –  Chris Down May 17 '13 at 17:38
    
@ChrisDown, though that's true of other shells, you don't need the closing semicolon in zsh. –  Stephane Chazelas May 18 '13 at 9:42
    
Also, this breaks if passing args to cd, like -P. –  Chris Down May 18 '13 at 11:37
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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