Sometimes the hardest part of improving your productivity is being able to notice that you’re doing something sub-optimal multiple times each day.
I was sitting hacking on some documents this morning when I realized that I frequently follow this usage pattern:
- Locate a file, using the locate command—often a Linux configuration file of some sort.
- Change directory to the directory containing that file, which is often a long way from the root directory or my current directory.
- Do some stuff using the file.
- Go back to what I was doing before.
A typical interaction:
w510:~/WIP 740$ locate s-pre-01.tex /usr/local/context/tex/texmf-context/tex/context/base/s-pre-01.tex w510:~/WIP 741$ cd /usr/local/context/tex/texmf-context/tex/context/base w510:/usr/local/context/tex/texmf-context/tex/context/base 742$ cp s-pre-01.tex ~/WIP/ w510:/usr/local/context/tex/texmf-context/tex/context/base 743$ cd ~/WIP/ w510:~/WIP 744$
The problem here is that long path. I either have to type it with assistance from tab completion, or copy and paste it using the mouse.
I realized it would be really handy if I could do something like cd `locate s-pre-01.tex`
Of course, that doesn’t work for a couple of reasons, most notably that locate outputs a path to a file, not to a directory.
I checked to see if locate had an option to output only the directory name of the match, or if cd had an option to accept a filename and move to the same directory as the file. No on both counts.
Next, I checked to see if something like cdargs would solve the problem, but it seemed not.
I had the feeling a lot of other people had probably wanted to do what I wanted to do, so my next stop was Google. That turned up unhelpful monstrosities like cd "$(dirname "$(find / -type f -name ls | head -1)")"
Due diligence done, it looked like I wasn’t about to reinvent the wheel. I hacked together a couple of bash shell functions. My new improved interaction:
w510:~/WIP 757$ cdlocate s-pre-01.tex w510:/usr/local/context/tex/texmf-context/tex/context/base 758$ cp s-pre-01.tex ~/WIP/ w510:/usr/local/context/tex/texmf-context/tex/context/base 759$ cd - /home/meta/WIP w510:~/WIP 760$
Note the use of cd -, an undocumented feature of bash which returns to the previous working directory. (It’s undocumented in help cd, at any rate.)