Created
August 18, 2011 14:04
-
-
Save derekwyatt/1154129 to your computer and use it in GitHub Desktop.
A BASH script to handle directory management
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export DIRSTACK_MAX=15 | |
DS=() | |
function eecho | |
{ | |
echo $@ 1>&2 | |
} | |
function shiftStackUp | |
{ | |
typeset num=$1 | |
typeset -i c=$((num+1)) | |
while (( $c < ${#DS[*]} )) | |
do | |
DS[$((c-1))]="${DS[$c]}" | |
((c=c+1)) | |
done | |
unset DS[$((${#DS[*]}-1))] | |
} | |
function shiftStackDown | |
{ | |
typeset num=$1 | |
typeset -i c=${#DS[*]} | |
while (( $c > $num )) | |
do | |
DS[$c]="${DS[$((c-1))]}" | |
((c=c-1)) | |
done | |
} | |
function popStack | |
{ | |
if [[ ${#DS[*]} == 0 ]]; then | |
eecho "Cannot pop stack. No elements to pop." | |
return 1 | |
fi | |
typeset retv="${DS[0]}" | |
shiftStackUp 0 | |
echo $retv | |
} | |
function pushStack | |
{ | |
typeset newvalue="$1" | |
typeset -i c=0 | |
while (( $c < ${#DS[*]} )) | |
do | |
if [[ "${DS[$c]}" == "$newvalue" ]]; then | |
shiftStackUp $c | |
else | |
((c=c+1)) | |
fi | |
done | |
shiftStackDown 0 | |
DS[0]="$newvalue" | |
if [[ ${#DS[*]} -gt $DIRSTACK_MAX ]]; then | |
unset DS[$((${#DS[*]}-1))] | |
fi | |
} | |
function cd_ | |
{ | |
typeset ret=0 | |
if [ $# == 0 ]; then | |
pd "$HOME" | |
ret=$? | |
elif [[ $# == 1 && "$1" == "-" ]]; then | |
pd | |
ret=$? | |
elif [ $# -gt 1 ]; then | |
typeset from="$1" | |
typeset to="$2" | |
typeset c=0 | |
typeset path= | |
typeset x=$(pwd) | |
typeset numberOfFroms=$(echo $x | tr '/' '\n' | grep "^$from$" | wc -l) | |
while [ $c -lt $numberOfFroms ] | |
do | |
path= | |
typeset subc=$c | |
typeset tokencount=0 | |
for subdir in $(echo $x | tr '/' '\n' | tail -n +2) | |
do | |
if [[ "$subdir" == "$from" ]]; then | |
if [ $subc -eq $tokencount ]; then | |
path="$path/$to" | |
subc=$((subc+1)) | |
else | |
path="$path/$from" | |
tokencount=$((tokencount+1)) | |
fi | |
else | |
path="$path/$subdir" | |
fi | |
done | |
if [ -d "$path" ]; then | |
break | |
fi | |
c=$((c=c+1)) | |
done | |
if [ "$path" == "$x" ]; then | |
echo "Bad substitution" | |
ret=1 | |
else | |
pd "$path" | |
ret=$? | |
fi | |
else | |
pd "$1" | |
ret=$? | |
fi | |
return $ret | |
} | |
function pd | |
{ | |
typeset dirname="${1-}" | |
typeset firstdir seconddir ret p oldDIRSTACK | |
if [ "$dirname" == "" ]; then | |
firstdir=$(pwd) | |
if [ ${#DS[*]} == 0 ]; then | |
eecho "Stack is empty. Cannot swap." | |
return 1 | |
fi | |
seconddir=$(popStack) | |
pushStack "$firstdir" | |
"cd" "$seconddir" | |
ret=$? | |
return $ret | |
else | |
if [ -d "$dirname" ]; then | |
if [ "$dirname" != '.' ]; then | |
pushStack "$(pwd)" | |
fi | |
"cd" "$dirname" | |
ret=$? | |
return $ret | |
else | |
eecho "bash: $dirname: not found" | |
return 1 | |
fi | |
fi | |
} | |
function ss | |
{ | |
typeset f x | |
typeset -i c=0 | |
typeset re="${1-}" | |
while (( $c < ${#DS[*]} )) | |
do | |
f=${DS[$c]} | |
if [[ -n "$re" && "$(echo $f | grep $re)" == "" ]]; then | |
((c=c+1)) | |
continue | |
fi | |
if (( ${#f} > 120 )); then | |
x="...$(echo $f | cut -c$((${#f}-120))-)" | |
else | |
x=$f | |
fi | |
echo "$((c+1))) $x" | |
((c=c+1)) | |
done | |
} | |
function csd | |
{ | |
typeset num=${1-} | |
typeset removedDirectory | |
# if [ "${num##+([0-9])}" != "" ]; then | |
if [ "$(echo $num | sed 's/^[0-9]*$//')" != "" ]; then | |
c=0 | |
re=$num | |
num=0 | |
while [ "$c" -lt "${#DS[*]}" ] | |
do | |
if echo "${DS[$c]}" | grep -q $re; then | |
num=$(($c+1)) | |
break | |
fi | |
((c=c+1)) | |
done | |
fi | |
if [ "$num" == 0 ]; then | |
echo "usage: csd <number greater than 0 | regular expression>" | |
return 1 | |
elif [ "$num" -gt "${#DS[*]}" ]; then | |
echo "$num is beyond the stack size." | |
return 1 | |
else | |
num=$((num-1)) | |
typeset dir="${DS[$num]}" | |
shiftStackUp $num | |
cd_ "$dir" | |
return $? | |
fi | |
} | |
alias cd=cd_ |
Hmm... I use 4.1.5(1) at work and 3.x at home and both work well. Can you put a set -x in the csd() function and post the output?
lionel:~/Projects$ ss
- /home/lionel
lionel:~/Projects$ cd slackbuilds/
lionel:~/Projects/slackbuilds$ ss - /home/lionel/Projects
- /home/lionel
lionel:~/Projects/slackbuilds$ set -x
lionel:~/Projects/slackbuilds$ csd 1
- csd 1
- typeset num=1
- typeset removedDirectory
- '[' 1 '!=' '' ']'
- c=0
- re=1
- num=0
- '[' 0 -lt 2 ']'
- grep -q 1
- echo /home/lionel/Projects
- (( c=c+1 ))
- '[' 1 -lt 2 ']'
- grep -q 1
- echo /home/lionel
- (( c=c+1 ))
- '[' 2 -lt 2 ']'
- '[' 0 == 0 ']'
- echo 'usage: csd
<number greater than 0 | regular expression>
'
usage: csd<number greater than 0 | regular expression>
- return 1
Try that... maybe your version of BASH has screwed up the variable regex stuff.
Hi Derek, your latest gist with the following line works -- thanks!
if [ "$(echo $num | sed 's/^[0-9]*$//')" != "" ]; then
No problem... your bash sucks :) (Either that or my 10 year old KSH / BASH / Mishmash isn't quite clean and beautiful :D)
Hi Derek. Have you got an updated revision now that you're working in Zsh?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi Derek, trying to get this to work in bash but running into a problem with csd
lionel:~/Projects/slackbuilds$ bash --version
GNU bash, version 4.1.10(2)-release (x86_64-slackware-linux-gnu)
lionel:~/Desktop$ ss
lionel:~/Desktop$ csd 1
usage: csd
<number greater than 0 | regular expression>
lionel:~/Desktop$ csd 2
usage: csd
<number greater than 0 | regular expression>
lionel:~/Desktop$ csd Projects
lionel:~/Projects$