传递目录模式作为参数来更改目录的解决方案

传递目录模式作为参数来更改目录的解决方案

我希望获得任何脚本或 Linux 解决方案来实现更改目录,不完全传递目录,而是传递模式作为参数。像这样的东西:

# Ex: I'd like to execute a "cd" to a directory with script as a part of it name. 
# My choice will be 4, so the script will execute cd /usr/share/doc/xorg-scripts-1.0.1

rexcd script

1) /home/prpe/scripts
2) /home/prpe/sintaxe/scripts_plone
3) /home/prpe/sintaxe/scripts_plone/scripts
4) /usr/share/doc/xorg-scripts-1.0.1
5) /usr/x86_64-pc-cygwin/lib/ldscripts

Option [1] 4

prpe@DESK-00-090117 /usr/share/doc/xorg-scripts-1.0.1
$

如果目录模式仅产生一个目录,则解决方案将对该目录执行 cd 命令。

感谢您提供任何解决方案或想法来实施它。

答案1

我想这个功能是你想要完成的吗?

rexcd () {
    search_base=/path/to/base
    pattern=$@

    directories=( $(find "$search_base" -type d -name "*${pattern}*" 2>/dev/null) )

    PS3="Which directory should we change to? "
    select dir in "${directories[@]}"; do
        case $dir in
            *) cd "$dir";break;;
        esac
    done
}

请注意,无论如何,在我的机器上,如果您搜索常用单词,这将显示很多您不想要的内容,具体取决于您的搜索基础的广泛程度。

正在使用:

$ rexcd someweirddir && pwd
1) /Users/jessebutryn/tmp/someweirddir1
2) /Users/jessebutryn/tmp/someweirddir2
Which directory should we change to? 2
/Users/jessebutryn/tmp/someweirddir2

答案2

您正在寻找使用以下select语句:

select dir in /place1 /other/place /path/to/elsewhere; do cd "$dir"; break; done

答案3

在收集并加入所有想法/建议后,我构建了这个脚本。标题部分解释了如何使用它以及对新开关的建议。快完成了:)

#!/bin/bash
# /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# * File       : rexcd.sh
# * Goal       : improve cd linux command
# * Requisites :
# *     1. SHELL=bash
# *     2. Locate service available and up to date. It's necessary to search directories
# *        (see locate, locatedb and updatedb manual for more information)
# * History    :
# *   #version;date;description
# *   0.1.1; 02/05/2018; tested in ubuntu 16.04/bash and minor code improvements
# *   0.1.0; 30/04/2018; first release (tested in cygwin 2.10.x)
# */

#
# How to use
#
# 1. put this script into a directory (Ex: ~/scripts)
#
# 2. insert this code in your ~/.bashrc:
# . ~/scripts/rexcd.sh
#
# 3. open a new shell session and test it:
# cd ~
# rexcd scripts
#
# 4. Example of output (cygwin 2.10.x)
# Choose one directory
# 
# 1) /home/prpe/scripts
# 2) /home/prpe/sintaxe/scripts_plone
# 3) /home/prpe/sintaxe/scripts_plone/scripts
# 4) /usr/share/doc/xorg-scripts-1.0.1
# 5) /usr/x86_64-pc-cygwin/lib/ldscripts
# Option [1] 2
# 
#  
# prpe@DESK-00-090117 ~/sintaxe/scripts_plone
# $

#
# ToDo:
#
# 1. switch:-i (ignore case)
# 2. switch:-l limits of directories in menu (from m-th to n-th search matches)  (m,n|m,|,n default 1 to number of matches)
# 3. switch:-d root directory -d <dir> (default /)
# 4. switch:-u perform an update of locatedb table
#

# syntax: rexcd_exit <msg>
function rexcd_exit {
    local msg=$1
    echo "${msg}" >&2
    return 1
}

# syntax: 
#  export rexcd_opt=""
#  rexcd_menu opt1 opt2 ... optn
#  echo $rexcd_opt
function rexcd_menu {
    # return code + option
    local FN_RESULT=1
    rexcd_opt=""

    # variáveis de controle
    local num_options=$#
    local arr_options
    local num_choose=1
    local FN_DEFAULT=""
    local v_aux1 v_aux2
    local fl ind

    # menu message
    local FN_MSG="Choose one directory "
    local PS3="#"

    # checking number of options and creating list of them
    if [ $num_options -lt 2 ]; then
        rexcd_exit "At least 2 options required"
        return $?
    fi

    let ind=1
    for fl in $*; do
        arr_options[${ind}]="${fl}"
        let ind++
    done

    # menu
    FN_RESULT=1
    ind=1
    num_choose=""
    FN_DEFAULT=$ind
    PS3="Option [${FN_DEFAULT}] "

    echo "" ; echo "${FN_MSG}" ; echo ""
    select num_choose in `echo ${arr_options[@]}`; do
        case "${num_choose}" in
            *)
                if [ -z "${num_choose}" ]; then
                    read -t 2 -p "Invalid option"
                    echo "" ; echo "${FN_MSG}" ; echo ""
                    continue
                fi
                FN_RESULT=0
                break
                ;;
        esac
    done
    echo ""

    rexcd_opt="${num_choose}"
    return ${FN_RESULT}
}

function rexcd {
    local contador fl
    local padrao=""
    local max_opc=15
    local lst_opc=""
    local retorno=0
    local v_aux=0

    # its necessary declare as export
    export rexcd_opt=""

    if [ $# -ne 1 ]; then
        rexcd_exit "Number of arguments invalid: $#. Must be exactly one."
        return $?
    fi

    padrao=$1
    contador=0
    cd /
    for fl in `locate -i "${padrao}"`; do
        # filter not directories elements
        [ ! -d "${fl}" ] && continue

        # search regards
        basename "${fl}" | grep -q -i "${padrao}"
        [ $? -ne 0 ] && continue


        # update array e var count
        let v_aux=contador+1

        if [ $contador -eq 1 ]; then
            lst_opc="${fl}"
        else
            lst_opc="${lst_opc} ${fl}"
        fi

        let contador++
        # verifica o máximo de entrada
        if [ $contador -ge $max_opc ]; then
            echo "WARNING: Maximum number of options $max_opc reached" >&2
            break
        fi
    done

    if [ ${contador} -eq 1 ]; then
        rexcd_opt="${lst_opc}"
    elif [ ${contador} -gt 1 ]; then
        export rexcd_opt=""
        rexcd_menu ${lst_opc}
        retorno=$?
    else
        rexcd_exit "No directory matches with ${padrao}."
        retorno=$?
    fi

    [ $retorno -eq 0 ] && cd ${rexcd_opt}
    return ${retorno}
}

相关内容