【问题标题】:How can I extract the last X folders from the path in k shell如何从 k shell 的路径中提取最后一个 X 文件夹
【发布时间】:2016-03-08 16:46:48
【问题描述】:

假设我有一个路径名/server/user/folderA/folderB/folderC,我将如何提取(到变量)最后几个文件夹?我正在寻找足够灵活的东西给我folderC,或folderB/folderC,或folderA/folderB/folderC等。

我正在尝试使用 sed,但我不确定这是最好的方法。

这必须在 ksh 或 csh 中(遗憾的是,我们的机器上没有 bash)

【问题讨论】:

    标签: shell sed ksh csh


    【解决方案1】:

    这会让你开始:

    arr=( $(echo "/server/user/folderA/folderB/folderC" | sed 's#/# #g') )
    
    echo ${#arr[*]}
    echo ${arr[*]}
    echo ${arr[3]}
    echo "${arr[2]}/${arr[3]}/${arr[4]}"
    

    输出

     5
     server user folderA folderB folderC
     folderB
     folderA/folderB/folderC
    

    IHTH

    【讨论】:

    • 我在 ksh 上收到关于括号 /Test.ksh[3]: syntax error at line 5 : (' unexpected 的错误
    • 第 5 行是您的初始 arr=( $(echo "/server/user/folderA/folderB/folderC" | sed 's#/# #g') )
    • 它在我的另一台运行 bash 的机器上完美运行,但我需要它的机器只支持 csh 和 ksh
    • 我可以看到 sed 行正在用空格替换'/',现在的问题是如何将包含空格的字符串分解为数组。
    • 你是 /bin/ksh 是 ksh 88 版本。在您的系统中查找 ksh93,或者如果在 Sun 上,请查找 /usr/xpg4/bin/ksh*。我不确定您关于“包含空格的字符串”的评论/问题是指什么。如果这是一个问题,请发布一个新的 Q,其中包含示例输入和来自同一输入的所需输出。祝你好运。
    【解决方案2】:

    如果你有的话,这可以用 perl 来完成:

    $ path=/server/user/folderA/folderB/folderC
    $ X=3
    $ echo $path|perl -F/ -ane '{print join "/",@F[(@F-'$X')..(@F-1)]}'
    folderA/folderB/folderC
    

    【讨论】:

    • 效果很好,谢谢!我还想找到一个非 perl 解决方案(因为我从来都不是 100% 可用的),但这将在 3 行中完美地完成这项工作。
    【解决方案3】:

    您可以使用数组,但 ksh88(至少是我在 Solaris 8 上测试过的那个)使用 set -A 的旧 Korn Shell 语法,而且它也不使用 (( i++ )),所以这看起来有点比当代 ksh93 或 mksh 代码更巴洛克。另一方面,我也给你一个函数来提取最后的 n 个项目;)

    p=/server/user/folderA/folderB/folderC
    saveIFS=$IFS
    IFS=/
    set -A fullpath -- $p
    echo all: "${fullpath[*]}"
    unset fullpath[0] # leading slash
    unset fullpath[1]
    unset fullpath[2]
    echo all but first two: "${fullpath[*]}"
    IFS=$saveIFS
    
    # example function to get the last n:
    function pathlast {
            typeset saveIFS parr i=0 n
    
            saveIFS=$IFS
            IFS=/
            set -A parr -- $2
            (( n = ${#parr[*]} - $1 ))
            while (( i < n )); do
                    unset parr[i]
                    (( i += 1 ))
            done
            echo "${parr[*]}"
            IFS=$saveIFS
    }
    
    for lst in 1 2 3; do
            echo all but last $lst: $(pathlast $lst "$p")
    done
    

    输出:

    tg@stinky:~ $ /bin/ksh x
    all: /server/user/folderA/folderB/folderC
    all but first two: folderA/folderB/folderC
    all but last 1: folderC
    all but last 2: folderB/folderC
    all but last 3: folderA/folderB/folderC
    

    除第一行设置$p外,只复制函数部分即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-17
      • 2014-12-11
      • 2013-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多