查找新文件夹的索引

时间:2017-05-11 14:14:05

标签: linux bash shell

我有一个名字,我应该用这个名字做一个目录。如果此目录已存在,则该文件夹的名称应为_ $ number作为其后缀。

数字计算为最高值+ 1.示例:

  

名称:真棒
  文件:虚拟真棒awesome_2 awesome_4 dummy_3
  新文件夹:awesome_5

     

名称:真棒
  文件:dummy dummy_1
  新文件夹:太棒了

我找到最高价值的解决方案仅适用于没有特殊字符的名称。该名称应该是例如:“$#& *!(@ (%+#$ asdasd \ ^ sad”,它会失败。

function max_item() { 

    local prefix="$1"
    local max="0"

    shopt -s nullglob

    for in_file in * ; do
        if [[ "$in_file" =~ ^"$prefix"_(-{0,1}[0-9][0-9]*)$ ]]; then 

            num="${BASH_REMATCH[1]}"; 
            [[ "$max" -lt "$num" ]] && max="$num"; 

        fi
    done

    echo "$max"
    shopt -u nullglob
    return 0
}

我想它与正则表达式中的特殊字符有关,但我已经用尽了所有的想法。

1 个答案:

答案 0 :(得分:2)

在shell代码中循环非常慢。

对于号码,codeforester's solution很好,但从大约30个项目开始(具体数量取决于很多因素),外部以下基于实用性的解决方案将更快,更好地扩展。
(对于较少的项目,外部实用程序解决方案较慢,但这很少重要)。

以下解决方案具有更简洁的附加优势:

max_index() {
  printf '%d\n' "$(shopt -s nullglob;
                   printf '%s\n' "$1_"* | 
                     awk -F_ '{print $NF}' | 
                       sort -rn | head -n 1)"
}

注意:合理的假设是您的文件名没有嵌入换行符。

  • shopt -s nullglob确保如果一个globbing模式(在这种情况下为"$1_"*)匹配任何内容,它会扩展为null(空)字符串。

  • printf '%s\n' "$1_"*逐行打印所有匹配的文件系统项。

  • awk -F_ '{print $NF}'在每一行输出最后一个_的标记,即尾随数字。

    • 注意:cut -d_ -f2也可以使用,但假设文件名中只有一个 _
  • sort -rn以数字方式(-n)排序后跟数字(-r)。

  • head -n 1然后只提取第一个输出行,根据定义,它是最高数字(如果有的话)。

请注意,printf '%d\n' ''输出0,如果找不到现有的_<number>后缀,则会发生这种情况。