LINUX.ORG.RU

test [[:digit:]] / range

 ,


0

1

Залип в очередном скрипте над разными проверками на digit-only / digit-in-range
Написать-то чтоб работало я могу по-разному.

Вобщем вопрос только как по баш-хакерски наиболее компактно написать последнюю конструкцию, а-ля ^[[:digit:]]*$

V="$1"
echo "-------------------------------"
# Работает, но может выдавать ложные позитивные, при конструкции вроде {{1..3},{100..120}}, где 10 не входит, но будет найдено в 110
# Можно как массив дотошнить, но слишком уныло.
[[ `echo {1..999}` = *"$V"* ]] && echo "$V > in range" || echo "$V > out of range"

# Проверка на [0-9]* работает корректно. Но громоздкая конструкция.
if `grep -Eqo "^[[:digit:]]*$"<<<$V` ; then
  echo 'true'
else
  echo 'false'
fi

# Почти компактный, наркоманский, вариант проверки.
grep -Eqo "^[[:digit:]]*$"<<<$V ; [[ "$?" = 0 ]] && echo 'digit' || echo 'not digit'



# А хочу конструкции вроде этой ^[[:digit:]]*$ , по аналогии с grep, но чисто на bash, проверять [0-9]*
[[ $V = <bash_magic_regex> ]] && echo "$V > YES!" || echo "$V > NO!"

# [[ $V = [[:digit:]]{1,3} ]] # Или вот такой...
★☆

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

Любой набор только цифр от начала и до конца строки, же.
Но это как бы пример, я не понял как это именно там написать.

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

Если тебе только проверить, то

[ "${V//[0-9]/}" ] && echo 'Not a digit…' || echo 'Digit!'
И кавычки не забывай у переменных внутри выражений. А то можешь получить интересные ошибки в команде test, когда строка вдруг окажется пустой.

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

Хотя по хорошему там должна быть предварительная проверка на пустую строку

[ "$V" ] && [ -z "${V//[0-9]/}" ] && echo 'Digit!' || echo 'Not a digit…'

Deleted
()
Последнее исправление: fargred (всего исправлений: 1)
Ответ на: комментарий от Deleted
${V//[0-9]/}

Ага, вкурил, поиск/удаление всех цифр, возврат нулевой строки. Изящно :3

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

bash уже пару лет, то ли с 4.0, то ли с 4.2, как поддерживает сравнение с регулярным выражением:

[[ "$V" =~ ^[0-9]*$ ]] && echo ih

---

Поздравляю, у меня для тебя две награды:

> if `grep -Eqo "^[[:digit:]]*$"<<<$V` ; then

Useless use of bacticks award!

> grep -Eqo "^[[:digit:]]*$"<<<$V ; [[ "$?" = 0 ]] && echo 'digit' || echo 'not digit'
Useless use of test award!

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

Уже несколько дней ломаю голову и перечитываю доку и не могу найти как указывать ИЛИ, те | или \| внутри расширенных переменных. Например

# С этим всё ясно
v="abcdEFGH12345" ; echo "${v//[ad]/_}"
# каждый символ из, или [a-d] все из диапазона

s="abc acc cbc cca abccbcacc" ; echo "${s//abc.ИЛИ.acc/}" ; sed -r 's/abc|acc/.../g'<<<$s
#  ^^^ ^^^         ^^^   ^^^    вот такой вот вариант не могу сообразить.

Неужели в variable expansion нет И/ИЛИ или как его там?

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

А ты вместо того чтобы читать «адванснутые» руководства, называя их «доками», прочти лучше bash(1).

       ${parameter/pattern/string}
              Pattern  substitution.  The pattern is expanded to produce a pattern
              just as in  just as in pathname expansion.

pathname expansion

и далее там же что есть, а чего нет в шаблоне.

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

В общем понятно, что можно так, а вот как один regex составить не нашёл.

s="abc acc cbc cca abccbcacc"
s="${s//abc}"
s="${s//acc}"
echo "$s"
Umberto ★☆
() автор топика
Ответ на: комментарий от ABW

Да, extglob, как-то просмотрел.

shopt -s extglob
s="abc acc cbc cca abccbcacc 1c2" ; echo "${s//+(abc|acc)/_}" 
Umberto ★☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.