디렉터리 모드를 매개변수로 전달하여 디렉터리를 변경하는 솔루션

디렉터리 모드를 매개변수로 전달하여 디렉터리를 변경하는 솔루션

디렉터리를 정확하게 전달하지 않고 패턴을 매개변수로 전달하여 디렉터리 변경을 구현하는 스크립트나 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
$

디렉터리 모드가 디렉터리를 하나만 생성하는 경우 솔루션은 해당 디렉터리로 이동합니다.

이를 구현하기 위한 솔루션이나 아이디어에 감사드립니다.

답변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}
}

관련 정보