views:

51

answers:

2

I'm looking for a way to find what I know will be a unique file, and then change into the directory containing that file. Something along the lines of:
find . -name 'Subscription.java' | xargs cd
Or:
find . -name 'Subscription.java' -exec cd {} \;
I know this won't work because it's both trying to cd supplying the entire absolute path, which contains the file, and also because xargs can't do any built in shell commands...but you get the point of what I want to accomplish.

+6  A: 
cd $(find . -name Subscription.java | xargs dirname)
Kevin Panko
Exactly the command I was looking for. I knew it was out there, but didn't know what the damn command was. Awesome. Thanks.
bergyman
And for anyone else that didn't know how to do this, I just slapped it into a shell function: function fcd() { cd $(find . -name $1 | xargs dirname) }
bergyman
`cd $(dirname $(find . -name $1 | sed 1q))` deals with non-unique names by going to the first one found and goes home if the name is not found. It also demonstrates nested use of `$(...)` which is why that notation is preferred over backticks. You might prefer '`sed '2,$d'`' since it avoids SIGPIPE errors messing with `find`.
Jonathan Leffler
Nice with the sed 1q. I need to look more into sed - I don't know much about it.
bergyman
Other useful variations if you want to go to the directory where an executable in the path is: `wcd () { cd $(dirname $(which $1)); }` or `wcd () { cd $(dirname $(type -p $1)); }` or `wcd () { local dir=$(type -P $1); [[ -z $dir ]] cd "${dir%/*}"; }`. The last one doesn't spawn any externals and doesn't change directories if the name is not found.
Dennis Williamson
A: 

Any attempt to script a cd command must ensure that the command is run in the current shell. Otherwise if run in a child shell, it will not work as you need as the parent current working directory will not be changed.

GNU find has -printf which can be used print the directory of any found files. The output of find can be passed to cd with Command Substitution.

cd $(find . -name Subscription.java -printf '%h\n')

cd (in bash) ignores extra arguments so if multiple files are found, cd will change into the directory of the first found file.

camh