Bash function that changes directory

I have a common use case that I would like to write for a function: I often want cd in some directory to refer to some file.

My current workflow is as follows:

$ gem which rspec/core | xargs echo -n | pbcopy
$ cd *paste and delete end until direcory looks right*

<sub> Note: gem which rspec/coreprints something like "/Users/joshcheek/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.10.0/lib/rspec/core.rb" Sub>

I would like it to look like this:

$ gem which rspec/core | 2dir 3

What will cd me in "/Users/joshcheek/.rvm/gems/ruby-1.9.3-p125/gems/rspec-core-2.10.0" (passing the argument "3" tells it to remove "lib / rspec / core. rb "from the end)

This is the best I've got so far:

2dir() {
  read dir
  for i in $(seq 1 $1)
    do
      dir="${dir%/*}"
  done
  cd "$dir"
}

cd , . , , .

+3
5

:

2dir()
{
    name=${2:?'Usage: 2dir count path'}
    count=$1
    while [[ $count -gt 0 ]]; do name=$(dirname "$name"); ((count--)); done
    cd "$name"
}

:

2dir 3 $(gem which rspec/core)

, . cd () , . .

dir="${dir%/*}" dirname, , , ( , , ), 10, 5 .

+9

@Jonathan Leffler - count $( ) :

2dir() {
# If first arg is a number, use it as a trim count; otherwise assume 2
if [[ "$1" =~ ^[0-9]+$ ]]; then
    count="$1"
    shift
else
    count=2
fi

if [[ $# -lt 1 ]]; then  # Make sure a command was specified
    echo "Usage: 2dir [count] command [commandargs ...]" >&2
    return 1
fi

name="$("$@")"  # Execute the remaining args as a command to get the target directory
while [[ $count -gt 0 ]]; do name=$(dirname "$name"); ((count--)); done
cd "$name"
}

:

2dir 3 gem which rspec/core
2dir gem which rspec/core
+2

gem which rspec/core | 2dir 3 "" . . - , () . , .

, , . , -. :

2dir() {
  declare -ir snip="$1"
  declare dir="$2"
  for i in $(seq 1 "$snip"); do
      dir="${dir%/*}"
  done
  cd "$dir"
}

:

$ 2dir 3 "$(gem which rspec/core)"
+1

script . , , .

:

Linux-, . . script, , .

0

, :

2dir () {
    local levels name=${2:?"Usage: $FUNCNAME count path"};
    printf -v levels '%*s' "$1" '';
    cd "/${name%${levels// //*}}"
}

, (, echo "$PWD" "//foo/bar/baz" ).

, " ".

Edit:

​​ :

2dir () {
    local levels name=${2:?"Usage: $FUNCNAME count path"};
    printf -v levels '%*s' $1 '';
    name=/${name%${levels// //*}};
    cd "${name/\/\///}"
}
0

All Articles