Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

The accepted answer of this question Fast Ways of Cd'ing on *nix? mentions bash having CDPATH

is there an equivalent in windows?

so from any directory e.g. c:\windows>
I could do c:\windows>cd compbar* and it'd take me to m:\a\b\c\d\e\compbar

what if there are many compbar directories? well, the CDPATH solution is one solution, I suppose you order them it'd search through the CDPATH environment variable and choose the first.

I'd like that for windows.

share|improve this question
    
    
@Moab Can you be more specific about what method within powershell? –  barlop Dec 21 '10 at 17:17
    
It was a suggestion to investigate, not up on powershell myself, sorry. –  Moab Dec 21 '10 at 21:53
add comment

3 Answers

Here is a doskey macro that uses cdpath variable when changing directories.

cd=echo off&set _=$*\$tset _=%_:"=%&set _o=%CD%&set _c=%_:.=..\%$tset_=%_:/=\%$tif "%_:~0,3%" equ "..." set _=..\%_c:~5%$tif "%_%" equ "-\" set _=%OLDPWD%$tfor %V in (" ";"%CDPATH:;=\";"%\") do if defined _c chdir /d "%~V%_%" 2>nul&&set _c=&&set OLDPWD=%_o%$tif defined _c echo Directory "%_:~0,-1%" not found$tfor %V in ("%CD:\=" "%") do if "%~V" neq "" set _=%~V$ttitle %_% - %CD%&set _=&set _c=&set _o=&echo on

Here is my cdpath:

CDPATH=.\;..\;c:\;C:\Program Files\;C:\work

In the work directory is a directory called perlscripts.

You can type cd perls* and you will change directory to C:\work\perlscripts


  • cd -     change directory to previous directory
  • cd       change to root directory
  • cd ..     move up one directory
  • cd ...    move up two directories
  • cd ....   move up three directories

...and so on.

Here is a doskey macro to view cdpath

cdpath=set _a=echo.^&echo.CDPATH = %cdpath:;=^&echo.%$t%_a%$tset _a=

CDPATH = .\
         ..\
         c:\
         C:\Program Files\
         C:\work
share|improve this answer
    
Ron, please edit and fix your formatting if you can. You need to indent code by 4 spaces. Thank you! –  slhck May 17 '13 at 19:51
add comment
CDPATH for cmd (dos) and much more.
**by moshahmed/at/gmail
You will need to install c:/cygwin/bin/bash.exe and perl.exe
Trick #1. in cdx.bat is to call a bash and perl script to set env variables:**

c:\> cat cdx.bat

@rem usage: cdx [dir] .. directory to cd to, will search dir in CDPATH
@rem Does: PWD_STACK=%PWD%,%PWD_STACK%, for use with 'cdx -'

@for /f "delims=" %%a in ('perl ~/perl/cdxx.pl "%PWD_STACK%" ') do @set PWD_STACK=%%a

@for /f "delims=" %%a in ('bash cdxx.sh %*') do @set CDX=%%a
@cd /d %CDX%

@for /f "delims=" %%a in ('perl ~/perl/cdxx.pl -v "%PWD_STACK%" ') do @set PWD_STACK=%%a

c:\> cat cdxx.pl

# What: push CWD onto the PWD_STACK, used by cdx.bat
#   Does: PWD_STACK=%PWD%,%PWD_STACK%

my (%seen);
my $verbose=0;
my $cwd = `cygpath -dasm .`; chomp $cwd;
my $xwd = `cygpath -lam .`;  chomp $xwd;

while( $_ = $ARGV[0], defined($_) && m/^-/ ){ shift; last if /^--$/; if(0){
  }elsif( m/^-v$/    ){ $verbose++;
  }
}

my ($stk) = shift;
my (@stk) = split(/,/, $stk);

my $result = $cwd;

my $num=1;
my $result_numbered = "d$num=$cwd";
$seen{$cwd}++;

for (@stk) {
  next if $seen{$_}++;
  $result .= ",$_";
  $num++;
  $result_numbered   .= ", d$num=$_";
}
warn "cdxx.pl @ARGV => PWD_STACK=$ENV{PWD_STACK}\n" if $verbose > 1;
warn "XWD=\"$xwd\"\n" if $verbose > 1;
warn "PWD_STACK=[ $result_numbered ]\n" if $verbose > 0;
print $result;  

C:\> cat cdx.sh

# Called from cdx.bat, to change dir on any drive.
# Usage: cdxx [dir] [count] .. dir to search and echo the drive or path.
#  count to skip dirs, incase of multiple matching dirs.
# GPL(C) 2013, moshahmed/at/gmail

warn(){ echo "$1" 1>&2 ;} # Use warn or set -x, not echo for debugging.
warn_no_nl(){ echo -n "$1" 1>&2 ;} # echo without newline.
verbose(){ test -n "$VERBOSE" && warn "$*"  ;}
croak(){ echo ${1:-.} ; exit ;}

TOPDIRS=$HOME/cdx.txt

usage() {
  warn "
Usage: $0 [OPTIONS] DIR [COUNT] .. find DIR in CDPATH for cdx.bat
  DIR
    ABBREV     .. to list CDPATH
    / or select .. select a dir from $TOPDIRS
    //regexp   .. select a dir from $TOPDIRS =~ regexp
    /push      .. push PWD to $TOPDIRS (also ~/alias/pwdd.cmd)
    [A-Z]:/DIR .. Absolute paths with forward slashes.
    /DIR
    *DIR*      .. glob DIR in CDPATH
    .../DIR    .. find DIR in CDPATH

    cdx -      .. cd (pop PWD_STACK, push unique is implicit)
    cdx d2      .. cd (pop PWD_STACK 2)

  COUNT        .. skip COUNT initial matches (in case of multiple matches).
  OPTIONS:
    -a         .. to list CDPATH and abbreviations of DIRS.
    -h         .. help
    -x         .. set -x for debug
    -v         .. verbose
"
    croak;  
}


CWD_BS=$(cygpath -das .) # e.g. CWD_BS=C:\home to match backslashes in PWD_STACK
CWD_FS=${CWD//\\//}      # e.g. CWD_FS=C:/home

# Process options.
opt_loop=true
while [ "$opt_loop" -a $# -gt 0 ]; do
  case "$1" in
    --)      opt_loop= ; shift; break ;;   # end options
    -x)      set -x ;;
    -a)      LIST_ABBREV=1 ;;
    -v)      VERBOSE=1 ;;
    -h|-?)   usage ;;
    *)       opt_loop=; break ;;  # non options
  esac
  shift # next option
done

test -n "$LIST_ABBREV" && set -x

if [[ -n "$LIST_ABBREV" || "$1" == "ABBREV" ]] ;then
  set +x ABBREV
  grep -P '\S\)\s+CDX=' c:/mosh/perl/$0 >&2
  warn "CDPATH contains: "
elif [[ $# < 1 ]];then 
  usage
fi

COUNT=${2:-1}

case "$1" in
    m|~)     CDX=$HOME  ;;
    # put your abbrevs here ;;
    /push)   echo $CWD_FS >> $TOPDIRS ;;
    //*|/|select)     
              case "$1" in
              //*) REGEXP=`expr -- $1 : '//\(.*\)'` ;;
                *) REGEXP=.  ;;
              esac
              TOPDIRS="$(grep -P "$REGEXP" $TOPDIRS |sort| uniq)"
              warn TOPDIRS=$TOPDIRS
              if [[ -z "$TOPDIRS" ]] ;then
                warn "Empty TOPDIRS"
                exit
              elif [[ -d "$TOPDIRS" ]] ;then # only one dir
                CDX=$TOPDIRS
              else
                select CDX in $TOPDIRS ;do
                  break
                done
              fi
             ;;
    ..)      CDX=.. ;;
    ...)     CDX=../.. ;;
    ....)    CDX=../../.. ;;
    */*)     CDX=$1 ;;
    *\\*)    CDX=$(cygpath -das "$1") ;;
    -|d[0-9]) # cdx [-,d1,d2,..]
            case $1 in
            -) COUNT=2 ;;
            *) COUNT=`expr -- $1 : 'd\(.*\)'` ;;
            esac
            IFS=','  
            for CDX in ${PWD_STACK:-.} ;do
              CDX=$CDX
              : $((--COUNT))
              if [[ $COUNT -gt 0 ]] ;then
                verbose warn "CDX=$CDX COUNT=$COUNT, skip"
                continue
              fi
              if [[ $CDX = $CWD_FS ]] ;then
                verbose warn "CDX=$CDX = PWD, skip"
                continue
              fi
              verbose "CDX=$CDX, COUNT=$COUNT"
              break
            done  
          ;;
    *)       CDX=no-such-dir ;;
esac

if [[ -d "$CDX" ]] ;then
  CDL=$(cygpath -law "$CDX") # Long name is ok.
  CDX=$CDL
  warn "CDX=$CDX"
  echo $CDX
  exit
fi

for DRIVE in . C: D: E: F: G: H: ;do # [[[1
  test -d "$DRIVE/" || continue;
  for CDPATH in \
      $DRIVE \
    ;do # [[[2 
    test -d "$CDPATH/" || continue

    case $1 in # [[[4 glob *$1* ?
      .../*) # SUBDIR search
          case $CDPATH in # skip top-level drives?
            [A-Z]:) continue ;;
          esac
          SUBDIR=`expr -- $1 : '\.\.\./\(.*\)'`
          verbose "find $CDPATH/ -d $SUBDIR"
          DIRS="$(find $CDPATH/ -name "$SUBDIR" -type d -print 2> /dev/null)"
        ;;
      ABBREV) warn "    $CDPATH" ;;
      *)
        verbose "Searching -d $1 in $CDPATH/"
        DIRS="$(find $CDPATH/ -maxdepth 1 -type d -name "$1" -print -quit 2> /dev/null)"
        ;;
    esac # ]]]4

    test -n "$DIRS" || continue
    verbose found DIRS=$DIRS

    for DIR in $DIRS ;do # [[[3
      test -n "$DIR" || continue
      test -d "$DIR" || continue

      if [[ $((--COUNT)) -gt 0 ]] ;then
        warn "Skipping -d $DIR, COUNT=$COUNT";
        continue
      fi

      warn "Found -d $DIR, COUNT=$COUNT";

      CDL=$(cygpath -law "$DIR")
      if [[ $CDL =~ ^[A-Z]:[a-zA-Z0-9/\\_-]+$ ]] ;then
        CDX=$CDL
      else
        CDX=$(cygpath -das "$DIR")
      fi

      echo "$CDX"
      exit
    done # ]]]3 DIRS
  done # ]]]2 CDPATH
done # ]]]1 DRIVE  
share|improve this answer
add comment

Take a look at "Cd Deluxe" for a greatly improved "change directory" command: http://www.plan10.com/cdd/.

share|improve this answer
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.