У меня есть каталог, в основном номера версий, и я пытаюсь определить тот, который отсортирован по версиям непосредственно перед другим конкретным.выбрать из отсортированного списка в bash
Основой здесь, опасаясь, что это проблема XY, является то, что эти номера версий получены из тегов git для веб-контента, и мы символизируем каталог public_html
для виртуального хоста сайта в каталог с версией.
Это выглядит примерно так:
drwxr-xr-x 8 graham www 17 Oct 17 2013 v2.0.10
drwxr-xr-x 8 graham www 17 Oct 17 2013 v2.0.11
drwxrwxr-x 8 graham www 17 Aug 29 2013 v2.0.8
drwxr-xr-x 8 brian www 17 Oct 17 2013 v2.0.9
...
drwxr-xr-x 9 graham www 21 Aug 5 2015 v4.19.0
drwxr-xr-x 10 graham www 19 Dec 17 2014 v4.2.0
drwxr-xr-x 9 brian www 21 Aug 10 2015 v4.20.0
drwxr-xr-x 9 brian www 21 Aug 10 2015 v4.20.0-fail
drwxr-xr-x 9 graham www 21 Aug 11 2015 v4.20.1
...
drwxr-xr-x 9 graham www 19 Mar 14 11:00 v4.35.0
drwxr-xr-x 9 graham www 19 Mar 14 13:28 v4.36.0
drwxr-xr-x 9 graham www 19 Mar 16 10:58 v4.36.1
lrwxr-xr-x 1 graham www 11 Mar 16 11:13 public_html -> v4.36.1
Символическая ссылка не всегда может указывать на самой последней версии (например, если мы должны были отступить из-за изменения). Моя цель - найти правильно названный каталог (т. Е. Мы пропустим *-fail
и т. П.), Который будет отсортирован до того, на который указывает public_html
.
Я в FreeBSD, так что моя stat
команда работает хорошо, как это:
read target <<<"$(stat -f'%Y' "${base}/public_html")"
Если вы в Linux, я понимаю, вы могли бы получить тот же эффект, что-то вроде этого:
target="$(stat -c '%N' "${base}/public_html")"
target="${target#* -> ?}"; target="${target%?}"
Но отсюда я не уверен, как я собираю номер версии. Обратите внимание, что я во FreeBSD, поэтому моя команда sort
не имеет опции -V
. Я пробовал два метода.
Первый обрабатывать петлю, а на содержимое каталога:
shopt -s extglob
while read this; do
[[ "$this" = "$target" ]] && break
previous="$this"
done < $(ls -1d v+([0-9]).+([0-9]).+([0-9]) | sort -n -t . -k1,1 -k2,2 -k3,3)
Второй очень похож, разборе массив вместо:
shopt -s extglob
a=($(ls -1d v+([0-9]).+([0-9]).+([0-9]) | sort -n -t . -k1,1 -k2,2 -k3,3))
for ((n=0; n<${#a[@]}; n++)); do
[[ "${a[$n]}" = "$target" ]] && break
previous="${a[$n]}"
done
Где оба эти падают является sort
, в котором первое поле не сортируется. Я подозреваю, что это потому, что оно не числовое (с «v» в начале, с разделителем «.»). Есть ли способ указать несколько разделителей или иначе «игнорировать» v
как-нибудь?
Или есть лучший способ справиться с этим, чем использовать внешнюю команду sort
, которая имеет непереносимые опции? Возможно, что-то внутреннее для баша?
Спасибо.
где вы видели '-V' вариант используется? Это обходной путь из-за отсутствия варианта версии. – karakfa
Извините, моя ошибка. Не могу прочитать сегодня днем. –