2017-05-11 103 views
2

我給了一個名字,我應該用這個名字做一個dir。如果這個目錄已經存在,該文件夾的名字應該有_ $數字作爲其後綴。查找新文件夾索引

數的計算公式爲最高值+ 1,例如:

名稱:真棒
文件:虛擬真棒awesome_2 awesome_4 dummy_3
新建文件夾:awesome_5

名稱:真棒
文件:虛擬dummy_1
新建文件夾:真棒

我找到最高價值的解決方案僅適用於沒有特殊字符的名稱。如果該名稱是例如:「$#& *(@(%+#$ asdasd \ ^難過!」,它失敗

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 
} 

我猜它是與特殊。 。正則表達式中的字符,但我已經用盡了我所有的想法

+2

你怎麼稱呼這個功能? – 123

+1

性能提示:代替'for f in *'在'$ {prefix} _「*'中使用'f可以節省大量無用的迭代。 – Jens

回答

2

既然你正在尋找一些在名稱末尾,由_前綴,你可以這樣做,而不是:

max=0 
number='^[[:digit:]]+$' 
for in_file in "${prefix}_"* ; do 
    num="${in_file##*_}" 
    [[ "$num" =~ $number ]] && [[ "$max" -lt "$num" ]] && max="$num" 
done 

num=$((max + 1)) 

我已經合併@Jens的優秀建議來循環通過匹配文件。

+1

123是對的,我通過前綴錯誤的方式,我的功能基本上工作,我只是不正確地調用它......然而,你的解決方案與@Jens性能改善是好多了,我會用它,非常感謝! – PesaThe

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確保,如果一個文件名匹配模式("$1_"*在這種情況下)沒有匹配項,它擴展爲空(空)字符串。

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

  • awk -F_ '{print $NF}'在每行上輸出最後的基於_的令牌,即尾隨號碼。

    • 注:cut -d_ -f2將工作太,但會假定只有一個_存在於文件名。
  • sort -rn數值進行排序的後數字(-n),在反向(-r)。

  • head -n 1然後只提取第一個輸出行,它根據定義是最高的數字(如果有的話)。

注意printf '%d\n' ''輸出0,這是有效的,如果沒有現成的_<number>後綴被發現會發生什麼。