Saturday, April 11, 2020

UNIX tip: "up", a better "cd"

This UNIX situation was always annoying to me:
$ cd a/b/c/d/e/f
$ ./some-cmd
$ cd ../../../../..
That is, typing all that ../../../../.. Even just "cd .." seems like a lot of characters to type for such a common task.

So years ago I created a shell function called up to handle cd-ing up the directory tree. If you use up with no arguments, it cds up one directory. But you can also tell it how many directories to cd up, which is where its power comes in. The above example becomes:
$ cd a/b/c/d/e/f
$ ./some-cmd
$ up 5
The shell function code is below. It works for bash and zsh, and it only uses shell builtins. I put this code in my .bashrc and .zshrc files.
function up()
{
 if [[ -z $1 ]]; then
   cd ..
 else
   if [[ $1 =~ [0-9]+ ]]; then
     local U=$(printf "%0${1}d" 0)
     cd ${U//0/'../'}
   else
     echo up: bad arg
   fi
 fi
}

A little explanation... The printf creates a string of N zeros, where N is the number of directories to cd up. The cd line uses the ${parameter/pattern/string} expansion to turn each "0" into a "../".

p.s. Yes, I know that pushd/popd solves the same problem, but I never got used to those. Also, I frequently cd down five directories, but then want to go up two. So for me, up is more versatile.