Как я могу убедиться, что строка Bash является буквенно-цифровой без подчеркивания?

Я добавляю в существующий сценарий функцию, которая позволит пользователю настроить имя хоста системы Linux. Правила, которые я применяю, следующие:

  • Должно быть от 2 до 63 символов.
  • Не должно начинаться или заканчиваться дефисом
  • Может содержать только буквенно-цифровые символы и дефисы; все остальные символы не разрешены (включая подчеркивание, что означает, что я не могу использовать символ регулярного выражения \W)

Я решил первые два в списке, но мне трудно понять, как проверить, содержит ли строка bash только буквы, цифры и дефисы. Я думаю, что могу сделать это с помощью регулярного выражения, но мне трудно понять, как это сделать (последний час я провел в Интернете и читал справочные страницы).

Я готов использовать sed, grep или любые другие стандартные инструменты, но не Perl или Python.


person Raam Dev    schedule 04.08.2009    source источник


Ответы (4)


Похоже, это должно сделать это:

^[a-zA-Z0-9][-a-zA-Z0-9]{0,61}[a-zA-Z0-9]$

Сопоставьте любой один буквенно-цифровой символ, затем сопоставьте до 61 буквенно-цифрового символа (включая дефисы), затем сопоставьте любой один буквенно-цифровой символ. Минимальная длина строки 2, максимальная 63. Не работает с Unicode. Если вам нужно, чтобы он работал с Unicode, вам нужно будет добавить другие классы символов вместо a-zA-Z0-9, но принцип будет тот же.

Я считаю, что правильное выражение grep, которое будет работать с Unicode:

^[[:alnum:]][-[:alnum:]]{0,61}[[:alnum:]]$

Пример использования:


echo 123-abc-098-xyz | grep -E '^[[:alnum:]][-[:alnum:]]{0,61}[[:alnum:]]$'

result=$(grep -E '^[[:alnum:]][-[:alnum:]]{0,61}[[:alnum:]]$' <<< "this-will-work"); echo $result;

echo "***_this_will_not_match_***" | grep -E '^[[:alnum:]][-[:alnum:]]{0,61}[[:alnum:]]$'
person Welbog    schedule 04.08.2009
comment
Как вы используете второе выражение с grep? Я ищу переключатели на странице руководства, но безуспешно: я повторяю строку, которая должна совпадать, и ничего не выводится. - person Alberto Zaccagni; 04.08.2009
comment
@Монтекристо: grep -E или egrep - person Welbog; 04.08.2009
comment
Я пробовал так: echo 1asdas*_- | grep -E '^[[:alnum:]][-[:alnum:]]{0,61}[[:alnum:]]$', без вывода (также без одинарных кавычек), лол, я должен спросить вопрос я думаю... :P - person Alberto Zaccagni; 05.08.2009
comment
@Montecristo: ваша тестовая строка содержит звездочку и подчеркивание и заканчивается дефисом, ни один из которых не разрешен выражением. - person Welbog; 05.08.2009
comment
@Welbog: Большое спасибо, я совершенно не понял, как это использовать: P - person Alberto Zaccagni; 05.08.2009
comment
[:alnum:] больше не содержит дефисов. - person Alston; 05.11.2015
comment
@Welbog Могу я спросить, почему символ ^ здесь [^[:alnum:]] представляет отрицательность (все не буквенные и числовые символы)? Но символ ^ здесь ^[[:alnum:]] представляет starts with? И вы упомянули, что он отлично работает с Unicode, у вас есть ссылка? Спасибо! - person Alston; 05.11.2015
comment
как F вы используете это - person Alexander Mills; 27.05.2018

Это bash-скрипт, проверяющий первый параметр, содержит ли он только буквенно-цифровые символы или дефисы. Он "передает" содержимое $1 в grep:

#!/bin/bash
if grep '^[-0-9a-zA-Z]*$' <<<$1 ;
  then echo ok;
  else echo ko;
fi
person js.    schedule 04.08.2009
comment
Почему ^ здесь представляет отрицательность вместо первого появления? - person Alston; 05.11.2015
comment
Это означает начало строки, поэтому каждый символ между ним и $ должен соответствовать шаблону. - person js.; 05.11.2015

Это последнее, что вам нужно: sed -e 's/[^[:alnum:]|-]//g'

person Alberto Zaccagni    schedule 04.08.2009

вы можете сделать это только с помощью bash

string="-sdfsf"
length=${#string}
if [ $length -lt 2 -o $length -gt 63 ] ;then
    echo "length invalid"
    exit
fi
case $string in
    -* ) echo "not ok : start with hyphen";exit ;;    
    *- ) echo "not ok : end with hyphen";exit ;;   
    *[^a-zA-Z0-9-]* ) echo "not ok : special character";exit;; 
esac
person ghostdog74    schedule 05.08.2009