Как сравнить две строки в формате версий, разделенных точками, в Bash?

Я не знаю ни одной из существующих, но вот как я создал свою темную тему.

  1. Перейдите в меню Theme->Customize Colors
  2. Нажмите на выделенную ссылку new theme и назовите свою тему
  3. Вернитесь в главное диалоговое окно темы, выберите все доступные цвета (нажмите на одну строку в этой таблице и нажмите Ctrl - a , чтобы выбрать все)
  4. (Необязательно) Если вы хотите изменить цвет, чтобы он немного отличался, нажмите кнопку Colorize (это самая правая кнопка в верхнем ряду)
  5. Нажмите кнопку Modify Hue/Saturation/Lightness (вторая справа в верхнем ряду). Переместите ползунки насыщенности и яркости влево, чтобы получить желаемый эффект (уменьшение насыщенности приводит к удалению цвета и делает все более серым, а уменьшение яркости делает вещи темнее без удаления цвета).

Я создал несколько «тем», подобных этой; более светлая / синяя тема, темная (серая) тема и темная (красная) тема.

157
задан codeforester 3 October 2017 в 20:53
поделиться

1 ответ

Ничего себе... это - путь вниз список старого вопроса, но я думаю, что это - довольно изящный ответ. Сначала преобразуйте каждую разделенную от точки версию в ее собственный массив, с помощью расширения параметра оболочки (См. Расширение Параметра Shell ).

v1="05.2.3"     # some evil examples that work here
v2="7.001.0.0"

declare -a v1_array=(${v1//./ })
declare -a v2_array=(${v2//./ })

Теперь два массива имеют номер версии как числовую строку в первоочередном заказе. Много вышеупомянутых решений берет Вас оттуда, но все это происходит из наблюдения, что строка версии является просто целым числом с произвольной основой. Мы можем протестировать нахождение первой неравной цифры (как strcmp, делает для символов в строке).

compare_version() {
  declare -a v1_array=(${1//./ })
  declare -a v2_array=(${2//./ })

  while [[ -nz $v1_array ]] || [[ -nz $v2_array ]]; do
    let v1_val=${v1_array:-0}  # this will remove any leading zeros
    let v2_val=${v2_array:-0}
    let result=$((v1_val-v2_val))

    if (( result != 0 )); then
      echo $result
      return
    fi

    v1_array=("${v1_array[@]:1}") # trim off the first "digit". it doesn't help
    v2_array=("${v2_array[@]:1}")
  done

  # if we get here, both the arrays are empty and neither has been numerically
  # different, which is equivalent to the two versions being equal

  echo 0
  return
}

Это повторяет отрицательное число, если первая версия является меньше, чем второе, нуль, если они равны и положительное число, если первая версия больше. Некоторый вывод:

$ compare_version 1 1.2
-2
$ compare_version "05.1.3" "5.001.03.0.0.0.1"
-1
$ compare_version "05.1.3" "5.001.03.0.0.0"
0
$ compare_version "05.1.3" "5.001.03.0"
0
$ compare_version "05.1.3" "5.001.30.0"
-27
$ compare_version "05.2.3" "7.001.0.0"
-2
$ compare_version "05.1.3" "5.001.30.0"
-27
$ compare_version "7.001.0.0" "05.1.3"
2

Вырожденные случаи как, ".2" или "3.0". не работайте (неопределенные результаты), и если нечисловые символы присутствуют около '.' этого, мог бы перестать работать (не протестировали), но конечно будет не определено. Таким образом, это должно быть соединено с функцией очистки или соответствующей проверкой на допустимое форматирование. Кроме того, я уверен с некоторой тонкой настройкой, это могло быть сделано более устойчивым без слишком большого количества дополнительного багажа.

0
ответ дан 23 November 2019 в 21:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: