bash shell练习3:实现push_d +n 与 pop_ +n

本文详细介绍如何使用bash shell编写代码,实现posh_d+n(将指定位置的目录移到栈顶)和pop_d+n(删除指定位置目录并调整栈)功能,同时处理包含空格的目录,并避免使用awk等工具。通过数组实现目录栈,详细解释了函数设计和测试过程。
摘要由CSDN通过智能技术生成

问题描述:

用bash shell 实现posh_d +n 以及 pop_d +n功能,具体要求:
  • 能处理包含空格的目录
  • 不能用上面例子的实现方式
  • 不能用awk等其他工具或者直接调用系统的push_d 及pop_d

实现思路:

  1. 使用数组实现目录栈,数组从下标0开始使用,数组长度-1的为栈顶,下标0的为栈底。

  2. push_d() 将可能参数划分为四种情况,并用flag变量记录,函数默认只有一个参数,将所有参数看成一个字符串($*)

      **push_d +n**
      将位置为 n (从栈顶目录开始数第n个) 的目录移至栈顶,其他目录下移,并 cd 至栈顶目录。
     参数n不能为负数或越界。
    
      **push_d dir**
       cd 至dir目录,并将当前目录压栈。
     第一次调用需将当前目录压栈,再 cd 至 dir 目录,并将 cd 后的目录压栈。
     需判断目录合法性,存在。下面代码不能处理名为 “+3” 这样的类似的目录。
    

push_d
  若当前数组中存在两个目录,交换栈顶目录和次栈顶目录位置,并 cd 至栈顶目录

flowchart1

  1. pop_d() 将可能参数划分为四种情况,并用flag变量记录,函数默认只有一个参数,将所有参数看成一个字符串($*)

pop_d +n
​ 将位置为 n (从栈顶目录开始数第n个) 的目录删除,其他目录下移。
​ 如参数为1,即删除的为栈顶目录,则 cd 至新栈顶目录。
​ 参数n不能为负数或越界。

pop_d
​ 若目录栈中存在两个以上目录,删除栈顶目录,并 cd 至 新栈顶目录
​ 存在一个目录,清空目录栈
​ 不存在目录,报错

flowchart2

  1. outDirArray()输出目录栈中目录,以回车分隔

实现代码:

#!bin/bash
push_d()
{
    #获取目录数组大小
    len=${#DIR_ARRAY[@]}
    #将所有参数提取为一个字符串
    param=$*  
    k=${param#+}

    #flag 记录参数四种情况
    #flag=0 ----不带参数   push_d
    #flag=1 ----+数字参数,且没有越界  push_d +n
    #flag=2 ----带目录参数,可能是非法或不存在的 push_d dir
    #flag=3 ----数字参数越界

    if [ -z  "${param}" ];  then
        #参数为空
        flag=0
    elif [ -n "$k" -a "$k" == "${k//[^0-9]/}" ]; then
        if ((k <= len)); then   
            #正常数字参数      
            flag=1
        else  
            #数字参数越界
            flag=3
        fi
    else
        #字符串参数
        flag=2
    fi
    
    case ${flag} in
    0)
        #若存在两个目录,交换栈顶目录和次栈顶目录位置,并 cd 至栈顶目录
        if ((len>=2));then
           index=$((len-1))   #栈顶目录下标
           temp=${DIR_ARRAY[index]}
           DIR_ARRAY[index]=${DIR_ARRAY[$((index-1))]}
           DIR_ARRAY[$((index-1))]=${temp}
           cd ${DIR_ARRAY[index]}
           outDirArray
        #栈中不存在两目录
        else
           echo "error:Two directories do not exist in the stack!"
        fi 
        ;;       
    1)
        #将位置为 k (从栈顶目录开始数第k个) 的目录移至栈顶,并 cd 至该目录
        temp=${DIR_ARRAY[$((len-k))]}
        for((i=len-k;i<len-1;i++))
        do
            DIR_ARRAY[i]=${DIR_ARRAY[i+1]}
        done
        DIR_ARRAY[$((len-1))]=${temp}
        cd ${DIR_ARRAY[$((len-1))]}
        outDirArray
        ;;
    2)
        #pushd的功能,将目录压栈并cd至该目录   
        dir=$param
        #如果栈空(数组空)  第一次使用push_d情况
        if ((len==0)); then 
            if [ -d "${dir}" ]; then    #判断目录是否存在
                DIR_ARRAY[0]=$(pwd)
                DIR_ARRAY[1]=$(pwd)"/"${dir}
                outDirArray
                cd "${dir}"
            else
                echo "error:directory does not exist or error!"
            fi
        elif [ -d "${dir}" ]; then      #判断目录是否存在
                cd "${dir}"
                DIR_ARRAY[$((len))]=$(pwd)
                outDirArray 
            else
                echo "error:directory does not exist or error!"
        fi
        ;;
    3)
        echo "error:Parameter out of bounds!"
        ;;
    *)  echo "error" 
    esac
}

pop_d()
{     
    len=${#DIR_ARRAY[@]} #获取目录数组大小
    param=$*
    k=${param#+}

    #flag 记录参数四种情况
    #flag=0 ----不带参数 pop_d
    #flag=1 ----+数字参数,且没有越界  pop_d +n
    #flag=2 ----数字参数越界
    #flag=3 ----参数语法错误

    if [ -z  "${param}" ];  then
        #参数为空
        flag=0
    elif [ -n "$k" -a "$k" == "${k//[^0-9]/}" ]; then
        if ((k <= len)); then   
            #正常数字参数      
            flag=1
        else  
            #数字参数越界
            flag=2
        fi
    else
        #字符串参数
        flag=3
    fi

    case ${flag} in
    0)
        #若目录栈大于1,删除当前栈顶目录,并 cd 至删除后栈顶目录
        if ((len>1));then
           index=$((len-1))   #栈顶目录下标
           unset DIR_ARRAY[index] 
           index=$((index-1))
           cd ${DIR_ARRAY[index]}
           outDirArray
        #栈中目录等于1
        elif ((len==1));then 
           unset DIR_ARRAY[0]
           outDirArray
        else
           echo "error:Two directories do not exist in the stack!"
        fi 
        ;;
    1)
        #将位置为 k (从栈顶目录开始数第k个) 的目录删除,如果删除的为栈顶目录(k=1),则cd 至下一栈顶目录
        if ((k==1));then
        {
            unset DIR_ARRAY[$((len-1))]
            cd ${DIR_ARRAY[$((len-2))]}
            outDirArray
        }
        else
            for((i=len-k;i<len-1;i++))
            do
                DIR_ARRAY[i]=${DIR_ARRAY[i+1]}
            done
            unset DIR_ARRAY[$((len-1))]
            outDirArray
        fi
        ;;
    2)
        echo "error:Parameter out of bounds!"
        ;;
    3)
        echo "error:Parameter error!"
        ;;
    *)  echo "error" 
    esac

}

#输出DIR_ARRAY 栈顶目录在数组元素最后 模仿pushd 逆序输出目录
outDirArray()
{
    len=${#DIR_ARRAY[@]}
    echo
    for((i=len-1;i>=0;i--))
    do
        echo ${DIR_ARRAY[i]}" "
    done
    echo
}

测试目录

测试结果

push_d dir

push_d +n

push_d

pop_d +n

在这里插入图片描述

pop_d

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值