One thing cmd.exe is better at than *nix shells (with default configuration)

I know the statement might be considered controversial. I even encourage you to try to prove me wrong, because I wish I knew better solution.

In my every day work I tend to use command prompt a lot. I have both cmd.exe and bash (from Git for Windows) opened all the time. My typical environment comprises numerous directories, I mean more than one hundred. Many of them share parts of their names. The names are long, dozens of characters. I have to move between them over and over again. The problem is that it is not feasible to type longish directory name many times manually.

Now, let’s suppose we have the following (shortened, of course) subdirectories structure of a directory which we are in at the moment:


When I would like to change the directory to bbaa in cmd.exe I type cd *aa* <Tab> <Tab>, I get the second result of auto completion, I press <Enter> and I have moved to bbaa. If I press <tab> three times, I get ccaadd. And when I press <tab> four times, I get eeaaff. This feature is brilliant. The auto completion works with wildcards and matches not only beginnings of a name. Last, but not least, it allows to cycle through suggestions while in-line editing a command.

The most important part here is: not only beginning of a name (which is, as far as I know, the behavior of a typical Unix shell) AND also ability to have the suggestions inserted in place, not only displayed them below the command prompt.

A Unix shell also does match wildcards, but only displays matched names. It does not offer (or I am not aware of it) a way to instantaneously pass matched name to a command. It only lists relevant suggestions and a user have to then manually re-edit the command so that it has desired argument. cmd.exe is better in that it allows a user to cycle through suggestions while in-line editing command argument. Which is great when it comes to long names of which only some parts can be conveniently memorized by a human.

I propose the following function which could be appended to .bashrc.

function cdg() { ls -d */ | grep -i "$1" | awk "{printf(\"%d : %s\n\", NR, \$0)}"; read choice; if [ "$choice" == "0" ]; then : ; else cd "`ls -d */ | grep -i \"$1\" | awk \"NR==$choice\"`"; fi; }

It is a simplistic function that searches through ls results with grep, parses them with awk and finally picks one of them and calls cd.

Now we can type cdg aa and we get all possible choices:

1 : aa/
2 : bbaa/
3 : ccaadd/
4 : eeaaff/

We simply type the number and we are done being moved to the desired directory. Without the need to manually re-enter the cd command with proper argument. Obviously, in cmd.exe we get this nice auto completion for every command typed in the interpreter, and my solution only solves changing directory use case in bash.

2014.02.02 UPDATE 1: After some deeper research, it turned out that the behavior of cmd.exe can be achieved in bash as well. The following line should be included into .bashrc:

bind '"\t":menu-complete'

However, my solution still serves the purpose as it uses grep -i which makes it case insensitive and thus renders it useful.

2014.02.06 UPDATE 2: I have experienced the second reason my solution is still relevant. It is much faster than pressing <tab> and waiting for the shell to suggest names. This can be observed in an environment with number of directories greater than a few, where MinGW tooling tends to be slow in general.

Leave a Reply

Your email address will not be published. Required fields are marked *

Protection against spam * Time limit is exhausted. Please reload CAPTCHA.