Увеличить на 1 последнее число в каталоге?

#bash

#bash

Вопрос:

Я хочу увеличить последнее число в каталоге, переданное в виде строки со следующей структурой.

Пример строки, которая будет передана, выглядит следующим образом: /efs/etc/alex15_0

После выполнения функции она станет /efs/etc/alex15_1

Число, которое я хочу увеличить, всегда находится после _ символа, который встречается только один раз, я полагаю, его можно использовать как индекс. Он будет увеличен на 1 без десятичных знаков, только обычные целые числа.

Я попытался захватить последний символ, используя

 ${str:$i:1}
 

Но это, очевидно, не сработает для таких случаев, как 99, которые превратятся в 910

В Java я бы взял индекс ‘_’, затем выделил подстроку по длине из этого индекса и увеличил его.

 str=/efs/etc/alex15_0
 updateVer()
{
}
 

Ответ №1:

Следующее должно сделать трюк:

 $ str=/efs/etc/alex15_0
$ echo ${str%_*}_$((${str##*_} 1))
/efs/etc/alex15_1
 

Способ, которым это работает, заключается в использовании 3 функций bash:

  1. Удалить соответствующий шаблон префикса. ${pattern%word} Это используется для удаления конечного числа и сохранения заголовка строки.

    Слово расширяется для создания шаблона так же, как при расширении имени пути. Если шаблон соответствует конечной части расширенного значения параметра, то результатом расширения является расширенное значение параметра с удалением кратчайшего совпадающего шаблона ( % случай) или самого длинного совпадающего шаблона ( %% случай).

  2. Удалить соответствующий шаблон префикса: ${parameter##word} используется для указания конечного числа после символа <подчеркивания>.

    Слово расширяется для создания шаблона так же, как при расширении имени пути. Если шаблон совпадает с началом значения параметра, то результатом расширения является расширенное значение параметра с удалением кратчайшего совпадающего шаблона ( # случай) или самого длинного совпадающего шаблона ( ## случай).

  3. Арифметическое расширение

    Арифметическое расширение позволяет вычислять арифметическое выражение и подстановку результата. Формат арифметического расширения:

     $((expression))
     

Комментарии:

1. @DDisciple Я сделал небольшое обновление для многозначных чисел

Ответ №2:

Все bash без расширенного глобулирования, на случай, если это кому-то поможет.

 echo ${dir%${dir##*_}}$((${dir##*_} 1))
 

Да, вы можете использовать расширение параметра в качестве модификатора для расширения параметра.

 $: dir=/efs/etc/alex15_0
$: echo ${dir##*_}        # remove everything up to last underscore
0
$: echo ${dir%${dir##*_}} # remove everything *after* "everything after the last underscore"
/efs/etc/alex15_
$: echo $((${dir##*_} 1)) # show everything after last _,  1
1
$: echo ${dir%${dir##*_}}$((${dir##*_} 1)) # stack it all together
/efs/etc/alex15_1
 

В основном то же самое, что и решение kvantour, просто играющее с многоуровневыми расширениями. 🙂

Ответ №3:

Если вы согласны, awk попробуйте выполнить следующее.

 echo "$val" | awk 'BEGIN{FS=OFS="_"} {$NF =1} 1'