linux下便捷高效地切换当前工作目录的技巧及脚本

介绍了一款名为djump的shell脚本工具,它可以帮助用户在Linux环境下实现目录的快速跳转。该工具支持创建标签、删除标签及列出所有标签等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

linux下便捷高效地切换当前工作目录的技巧及脚本

在linux下进行目录的频繁切换通常会用到dirs,pushd,popd等命令,但这样也会比较的繁琐;

本文通过linux基本命令封装了一个脚本,加载后只需通过一个djump命令即可完成目录的快速跳转;

使用方式,

首先source加载,可以直接写入 ~/.bashrc文件登录时自动加载;

比如保存为~/env/djump.sh文件,然后将这条语句写入~/.bashrc文件中

 [ -f ~/env/djump.sh ] && source ~/env/djump.sh

然后直接可以通过djump --help查看释放方法

执行djump --help查看使用帮助

可以快速的对所在目录创建tag,以及快速的跳转到指定tag所代表的目录;

#! /bin/bash
#
####################################################
# Filename    : djump.sh
# Author      : longbin
# Created date: 2017-03-31 19:16:19
####################################################
#
# change history
# v1.1 2020-05-04 merge dtag and duntag to djump --create, --delete.
# v1.2 2020-06-08 update interaction message.
# v1.3 2021-12-06 optimise process for 'OLDPWD not set'.
# v1.4 2022-03-25 update help info and comment.
# v1.5 2022-09-28 add color print for output.
# v1.6 2022-10-08 fix tag output alignment issue.

export __DJUMP_VERSION='v1.6'
export __DJUMP_DATA_PATH=${HOME}/.djump

[ -d ${__DJUMP_DATA_PATH} ] || mkdir -p ${__DJUMP_DATA_PATH} 2>/dev/null

function _djump_print_with_width()
{
    local min_width=${1}
    local tag_name=${*}
    tag_name=${tag_name#* } # remove 1st arg
    local out_length=${#tag_name}
    local blanks=' '

    for ((;out_length<min_width;out_length++))
    do
        # append blank
        blanks="${blanks}"' '
    done
    echo -n -e "${tag_name}${blanks}"
}

function _djump_list_tags()
{
    local tag_name=$1
    local tag_len=${#tag_name}
    local tag_matched=""
    local link_short_name=''
    local link_long_path=''
    local link_name_length=0
    local column_sep_ok='--->'
    local column_sep_ng='---x'
    local data_path=${__DJUMP_DATA_PATH}
    local tag_print_width=7
    local color_print=1

    # close color print for some terminal type
    case "${TERM}" in
        "xterm")
            color_print=0
            ;;
        *);;
    esac

    # echo "_djump_list_tags tag:${tag_name}, begin."
    # update tag_print_width
    local tag_list_details=$(ls -l --color=never ${data_path} | \
        awk '{
             if ($(NF-1)=="->") {
                 print $(NF-2)"->"$(NF)
             }
        }')

    # match tag_name and set print width
    for line in ${tag_list_details}
    do
        link_short_name=$(echo ${line} | awk -F'->' '{print $1}')
        if [ "${link_short_name:0:${tag_len}}" = "${tag_name}" ] ;then
            tag_matched="ok"
        fi

        if [ "${color_print}" != "0" ] ;then
            link_short_name="\033[36m${link_short_name}\033[0m"
        fi

        link_name_length=${#link_short_name}
        if [ "${link_name_length}" -gt "${tag_print_width}" ] ;then
            let tag_print_width=${link_name_length}
        fi
    done
    # no matched tag found
    if [ "${tag_matched}" != "ok" ] ;then
        tag_name=''
    fi

    # show detailed info of each tag
    for line in ${tag_list_details}
    do
        link_short_name=$(echo ${line} | awk -F'->' '{print $1}')
        link_long_path=$(echo ${line} | awk -F'->' '{print $2}')
        if [ "${link_short_name}" = "" ] ;then
            continue
        fi

        # echo "tag: ${tag_name}, link: ${link_short_name}"

        # if tag_name is not empty, show the specified tag info
        # else show each tag info
        if [ "${tag_name}" != "" ] ;then
            if [ "${tag_name}" != "${link_short_name:0:${tag_len}}" ] ;then
                continue
            fi
        fi

        # show tag name
        if [ "${color_print}" != "0" ] ;then
            link_short_name="\033[36m${link_short_name}\033[0m"
        fi
        _djump_print_with_width ${tag_print_width} ${link_short_name}

        # show detailed link path
        if [ -d ${link_long_path} ] ;then
            if [ "${color_print}" != "0" ] ;then
                link_long_path="\033[34m${link_long_path}\033[0m"
            fi
            _djump_print_with_width 0 "${column_sep_ok} ${link_long_path}"
        else
            if [ "${color_print}" != "0" ] ;then
                link_long_path="\033[40;31m${link_long_path}\033[0m"
            fi
            _djump_print_with_width 0 "${column_sep_ng} ${link_long_path}"
        fi
        echo ""
    done
}

function djump()
{
    local argv1=$1
    local argv2=$2
    local argv3=$3
    local data_path=${__DJUMP_DATA_PATH}
    local help_info="djump ${__DJUMP_VERSION}
    This tool can change work directory more easy and quickly.

Usage:
    djump [option] [tag_name]

Options:
    -j, --jump
        change directory to the tag_name represented.
        change directory to the last one if no tag_name specified.
        this is the default option.
    -l, --list
        list tags named like tag_name.
        list all tags when no tag_name specified.
    -c, --create
        create tag named as tag_name.
        tag_name cannot start with (-);
    -d, --delete
        delete tag named as tag_name;

Examples:
    djump                     change directory to the last one;
    djump -j                  change directory to the last one;
    djump --jump              change directory to the last one;

    djump        tag_name     change directory to the tag_name represented;
    djump -j     tag_name     change directory to the tag_name represented;
    djump --jump tag_name     change directory to the tag_name represented;

    djump -l                  list all tags created;
    djump --list              list all tags created;
    djump -l     tag_name     list tag named like tag_name;
    djump --list tag_name     list tag named like tag_name;

    djump -c       tag_name   create tag named as tag_name, tag_name cannot start with (-);
    djump --create tag_name   create tag named as tag_name, tag_name cannot start with (-);

    djump -d       tag_name   delete tag named as tag_name;
    djump --delete tag_name   delete tag named as tag_name;
"

    # show help info when argument is one of ?,-h,--help
    for arg in "$@"
    do
        # echo ${arg}
        case "${arg,,}" in
            '?')
                echo -e "${help_info}"
                return 0
                ;;
            '--help'|'-h')
                echo -e "${help_info}"
                return 0
                ;;
        esac
    done

    [ -d ${data_path} ] || mkdir -p ${data_path}
    if [ "$?" != "0" ] ;then
        echo "Error: permission denied."
        return 1
    fi

    # if no arg: cd -;
    # if only one arg: cd arg;
    # if option1 in ["--create", "--delete", "--list"] and has arg: do action with arg
    # otherwise show help info and options.
    if [ "${argv1:0:1}" = "-" ] ;then
        option1=${argv1}
        tag_name=${argv2}
        butt_arg=${argv3}
    else
        option1='--jump' # jump is the default option.
        tag_name=${argv1}
        butt_arg=${argv2}
    fi

    if [ "${tag_name:0:1}" = "-" ] ;then
        echo "Error: invalid tag_name: cannot start with (-)"
        echo -e "${help_info}"
        return 1
    fi

    # butt_arg should be empty, the cmd at most has cmd, opt, tag.
    if [ "${butt_arg}" != "" ] ;then
        echo "Error: invalid parameters."
        # show all created tag
        echo -e "${help_info}"
        return 1
    fi

    case "${option1,,}" in
        '-j'|'--jump')
            # jump
            if [ "${tag_name}" = '' ] ;then
                if [ "${OLDPWD}" != '' ] ;then
                    cd -
                fi
                return 0
            fi

            if [ -L ${data_path}/${tag_name} ] ;then
                if [ ! -d ${data_path}/${tag_name} ] ;then
                    # tag_name is a link file targeted to an invalid directory: invalid link.
                    echo "Error: ${tag_name}: Invalid source directory."
                    return 1
                fi

                # change directory to the path that tag represented.
                cd -P ${data_path}/${tag_name} 2>/dev/null
                if [ "$?" != "0" ] ;then
                    echo "Error: ${tag_name}: Invalid tag."
                    return 1
                fi
            else
                echo "Error: ${tag_name}: No such tag."
                if [ "$(ls ${data_path})" != "" ] ;then
                    echo -e "\nThe tag_name could be:"
                    for line in $(ls ${data_path})
                    do
                        echo -e "    ${line}"
                    done
                fi
                return 1
            fi
            ;;
        '-c'|'--create')
            # create tag
            if [ "${tag_name}" = "" ] ;then
                echo "Error: Invalid tag_name: cannot be empty."
                echo -e "${help_info}"
                return 1
            fi

            if [ -L ${data_path}/${tag_name} ] ;then
                echo "${tag_name}: already exists."
                read -p "update the tag ${tag_name} to $(pwd)? [y/N] " choice
                if [ "${choice,,}" = "y" ] ;then
                    rm -f ${data_path}/${tag_name}
                else
                    return
                fi
            fi

            # create a soft link to $(pwd) with the tag_name
            ln -s $(pwd) ${data_path}/${tag_name} 2>/dev/null
            if [ "$?" != "0" ] ;then
                echo "Error: permission denied."
                return 1
            fi
            ;;
        '-d'|'--delete')
            if [ "${tag_name}" = "" ] ;then
                echo "Error: Invalid tag_name: cannot be empty."
                # show all created tag_name
                echo -e "${help_info}"
                if [ "$(ls ${data_path})" != "" ] ;then
                    echo -e "\nThe tag_name could be:"
                    for line in $(ls ${data_path})
                    do
                        echo -e "    ${line}"
                    done
                fi
                return 1
            fi

            # delete tag_name link file if tag_name exists.
            if [ -L ${data_path}/${tag_name} ] ;then
                read -p "remove tag: \`${tag_name}'? [y/N] " choice
                if [ "${choice,,}" = "y" ] ;then
                    rm -f ${data_path}/${tag_name} 2>/dev/null
                    if [ "$?" != "0" ] ;then
                        echo "Error: permission denied."
                        return 1
                    fi
                fi
            else
                echo "Error: ${tag_name}: No such tag."
                return 1
            fi
            ;;
        '-l'|'--list')
            # list the specified tag info of tags start with tag_name,
            # or all tag info if empty tag_name or non-matched tag_name.
            _djump_list_tags ${tag_name}
            ;;
        *)
            echo "${option1}: Invalid option."
            echo -e "${help_info}"
            return 1
            ;;
    esac
    return 0
}

# to provide completion word for djump when double hit tab.
function _djump_completer()
{
    # compgen -W will match words starting with cur_word from word_list.
    # Command: compgen –w “aa ab bb cc” -- “a”;
    # means to match words starting with "a" from "aa ab bb cc",
    # The return result of this command is "aa ab".

    # COMP_CWORD is a system variable that indicates the current word index in command.
    local cur_word=${COMP_WORDS[COMP_CWORD]}
    local word_list=$(find ${__DJUMP_DATA_PATH} -maxdepth 1 -type l -printf "%f\n")
    #COMPREPLY=($(compgen -W '${word_list[@]}' -- "${cur_word}"))

    # echo -e "\n\t cmd is ${COMP_WORDS[0]}"
    # echo -e "\t argv1 is ${COMP_WORDS[1]}"
    # echo -e "\t argv2 is ${COMP_WORDS[2]}"
    # echo -e "${COMP_WORDS[0]}, ${COMP_WORDS[1]}\c"
    case ${COMP_CWORD} in
        0)  #command hasnt been completed yet, nothing to do here.
            #${COMP_WORDS[0]} is argv0(that is cmd).
            ;;
        1)  #command has been completed, begin to complete argv1.
            #${COMP_WORDS[0]} is command.
            #${COMP_WORDS[1]} is argv1.
            argv1=${COMP_WORDS[1]}
            if [ "${argv1:0:1}" = '-' ] ;then
                local option_list='-j --jump -c --create -d --delete -l --list'
                COMPREPLY=($(compgen -W '${option_list}' -- "${cur_word}"))
            else
                COMPREPLY=($(compgen -W '${word_list[@]}' -- "${cur_word}"))
            fi
            ;;
        2|*)#command and argv1 have been completed, begin to complete argv2.
            #${COMP_WORDS[1]} is argv1.
            case ${COMP_WORDS[1]} in
                '-j'|'--jump')
                    COMPREPLY=($(compgen -W '${word_list[@]}' -- "${cur_word}"))
                    ;;
                '-d'|'--delete')
                    COMPREPLY=($(compgen -W '${word_list[@]}' -- "${cur_word}"))
                    ;;
                '-l'|'--list')
                    COMPREPLY=($(compgen -W '${word_list[@]}' -- "${cur_word}"))
                    ;;
                *)
                    ;;
            esac
            ;;
    esac
}

complete -F _djump_completer djump

例如

[~]$ djump --help
djump v1.6
    This tool can change work directory more easy and quickly.

Usage:
    djump [option] [tag_name]

Options:
    -j, --jump
        change directory to the tag_name represented.
        change directory to the last one if no tag_name specified.
        this is the default option.
    -l, --list
        list tags named like tag_name.
        list all tags when no tag_name specified.
    -c, --create
        create tag named as tag_name.
        tag_name cannot start with (-);
    -d, --delete
        delete tag named as tag_name;

Examples:
    djump                     change directory to the last one;
    djump -j                  change directory to the last one;
    djump --jump              change directory to the last one;

    djump        tag_name     change directory to the tag_name represented;
    djump -j     tag_name     change directory to the tag_name represented;
    djump --jump tag_name     change directory to the tag_name represented;

    djump -l                  list all tags created;
    djump --list              list all tags created;
    djump -l     tag_name     list tag named like tag_name;
    djump --list tag_name     list tag named like tag_name;

    djump -c       tag_name   create tag named as tag_name, tag_name cannot start with (-);
    djump --create tag_name   create tag named as tag_name, tag_name cannot start with (-);

    djump -d       tag_name   delete tag named as tag_name;
    djump --delete tag_name   delete tag named as tag_name;

[~]$
[~]$ cd /mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$ 
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$ djump -c locservice.code
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$ 
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$ 
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$ cd
[~]$ 
[~]$ djump locservice.code 
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$ 
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$ djump
[~]$ 
[~]$ djump
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$ djump 
[~]$
[~]$ cd /mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$ djump -c locservice.build
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$ djump #连续按下[TAB][TAB]
locservice.build  locservice.code
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$ djump locservice.code 
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$ djump locservice.build 
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$ 
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$ 
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$ djump
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server]$ djump
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$ djump -l
locservice.build ----> /mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core
locservice.code  ----> /mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core/java/com/android/server
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$
[/mnt/android_code/code/v3.0/andrdoi_9.0/AOSP/frameworks/base/services/core]$


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值