LINUX.ORG.RU

bash диапазон

 


0

2

Имеется


ip=10.22.15.30

if [[ "$ip" =~ ^10.22.*|^10.29.* ]]; then
echo "good"
else
echo "bad" 
fi

Как проверять диапазон по регулярные выражению ip адресов 
необходимо проверять перемену ip от ^10.22.* до ^10.29.*
если в этот диапазон попадает,то good если нет bad

Вариант1: разбить IP на 4 октета и проверять как обычные Целые Числа

Вариант2: представить IP как 32битное целое число и проверять как обычное Целое Число

futurama ★★★ ()

Ржу. Выделяй второе число в ip

sed -E 's/^[0-9]*\.([0-9]*)\.[0-9]*\.[0-9]*$/\1/'
и сравнивай его с 22 и 29. Если нужна проверка и по «10», то и его выделяй.

anonymous ()

Да нате. Представляю, как вы будете это объяснять преподу...

IP1=10.22.0.0
IP2=10.29.255.255

ip2u32() {
        local o1 o2 o3 o4
        IFS=. read o1 o2 o3 o4 <<< "${!2}"
        eval $1='$((o4+o3*256+o2*256*256+o1*256*256*256))'
}

ip2u32 i1 IP1
ip2u32 i2 IP2
read -p "test ip: " TI
ip2u32 ti TI
((((ti>=i1)+(ti<=i2))==2)) && echo Ok
В отличии от regex, это будет работать с любыми валидными IPv4.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от KennyMinigun

Ну это уже изращение и правильная поддержка не гарантируется, потому и не используется почти нигде. Зато формату hosts(allow/deny), то бишь tcpd этот вариант как раз удовлетворит, как 127.1.0.0

vodz ★★★★★ ()
Ответ на: комментарий от madcore

Если уж за универсальность, то в общем случае может понадобиться матчить и что-то вроде 192.168.*.255

Это так кажется только с дивана. А как начнёшь реализовывать в коде, так сразу возникает, а как это описывать, если захочется 192.168.2-20.255, и вдруг окажется, что никакая ни прямая ни обратная маска не подходит и проще просто перечислить, то есть ЧТД — такая хочушка нафиг не надо.

vodz ★★★★★ ()
Ответ на: комментарий от Deleted

И что тут сложного? Если вы не умеете eval, то возьмите и прочитайте раздел документации об этом. Код простейший.

Кстати, из-за того, что там гарантированно получается число, то можно без кавычек.

vodz ★★★★★ ()
Ответ на: комментарий от Deleted

Не пойму хода мысли, зачем такое число 2886729729????

Эка, не ожидал такого. Тут bash вовсе не при чём.

0.0.0.1 - 0.0.0.255 это даст o4.

0.0.1.0 - 0.0.1.255 - это o4 + o3*256, то есть для 0.0.1.0 получим 256, который идёт сразу за 255 - максимальное значение восьмибитного октета.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Ну это уже изращение и правильная поддержка не гарантируется,

Да, та самая маргинальщина, которая заставляет пятую точку возгорать иногда.

Ради спортивного интереса я накостылял поддержку, но без царского анролла:

function ip2u32() {
  local octets=( ${1//./ } )
  
  local -i u32=${octets[-1]}
  unset octets[-1]

  local i
  for i in ${!octets[@]}; do
    u32+=$(( octets[i] * 256 ** (3 - i) ))
  done
  
  echo $u32
}

https://wandbox.org/permlink/yPxPssb8uZOejdpO

KennyMinigun ★★★★★ ()
Ответ на: комментарий от KennyMinigun

У меня версия bash не поддерживает unset octets[-1]. Да и вообще unset тормоз еще тот. Так что получилось как то так:

function ip2u32() {
  local -i o=( ${1//./ } )
  local -i last=${#o[@]}-1 u32
  u32=o[last]
  o[last]=0
  u32+=o[2]*256+o[1]*256*256+o[0]*256*256*256
  echo $u32
}
Обидно, что в одну строку local не работает.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Прикольно, не то, чтоб неожиданно, но удивило что математика включилась с u32 без дополнительных операторов.

Обидно, что в одну строку local не работает.

Кстати, на 4.3 заработало:

function ip2u32() {
  local -i o=( ${1//./ } ) last=${#o[@]}-1 u32=o[last]
  o[last]=0
  u32+=o[2]*256+o[1]*256**2+o[0]*256**3
  echo $u32
}

https://wandbox.org/permlink/EuZCP9jclrwFOKI8

KennyMinigun ★★★★★ ()
Последнее исправление: KennyMinigun (всего исправлений: 1)
Ответ на: комментарий от KennyMinigun

У этого есть некрасивый дефект: () скобочки надо экранировать. Но скорость хорошо возрастает при декларации с -i на больших скриптах.

Кстати, на 4.3 заработало:

Они уже задокументировали, что это так будет теперь всегда? Ну можно через несколько лет использовать, да.

256**2

Что-то я сомневаюсь, что там будет вычисляемая константа, проще уж сразу написать 65536

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от madcore

Ну или $(((o[2]<<8)+(o[1]<<16)+(o[0]<<24)))

Я это не стал предлагать, так как у нас не 80286 и вряд ли в тактах будет выигрыш, но вот скобочки всё портят. Ведь декларируя local -i мы от них избавились, но << их потребуют, и не потому, что приоритет операций, а потому что это будет кривой heredoc, ну либо \<\<, что ещё хужее.

vodz ★★★★★ ()
Ответ на: комментарий от anonymous

Как называется эта болезнь, когда воображают что выгадывают такты на скриптоте?

Я не знаю такой болезни. Зато знаю вашу. Ходите по всем моим сообщениям по пятам, демонстрируете полноё отсутствие знания bash и нифига не парсите в написанное, что на bash, что просто по-русски.

Для тупых повторяю: даже если оно будет оптимальнее, то незначительно, но скрипт будет испорчен для чтения многочисленными скобочками и слешами.

vodz ★★★★★ ()
Ответ на: комментарий от vodz

Они уже задокументировали, что это так будет теперь всегда?

Интересно, есть ли для баша (не Bourne и/или POSIX Shell) стандарт? :) КМК, реализация GNU Bash — референсная. Но поскольку некоторые шеллы (напр. zsh) поддерживают совместимость, некий (хотяб неписанный) стандарт должен быть.

Самое близкое, что удалось найти — reference manual (https://www.gnu.org/software/bash/manual/bash.pdf)

KennyMinigun ★★★★★ ()