В bash, как я могу проверить, начинается ли строка с некоторого значения?

Отображение того, что многие строки заставляют движок рендеринга браузера замедляться, а не движок JavaScript. К сожалению, вы ничего не можете с этим сделать.

Лучшее решение - просто не отображать столько строк одновременно, либо путем разбивки на страницы, либо виртуальной прокрутки.

631
задан the Tin Man 14 January 2016 в 22:16
поделиться

8 ответов

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

Поддержка регулярных выражений по существу подобна использованию компилятора внутри программы, который преобразует выражение в последовательность соответствующих инструкций. Вы должны будете построить все составляющие части: механизм перевода, ряд правил преобразования, DFA ассемблер, и соответствующий механизм.

Это говорит, что это не невозможно! Начните с небольших, поддерживающих крошечных подмножеств реального языка, который вы хотите поддерживать, а затем работать ваш путь вверх. Для получения подробной информации о том, как создать собственный механизм регулярных выражений, ознакомьтесь с главой 16 программы на языке сборки . Вам также потребуется хорошее понимание того, как они работают (что даст вам эта глава), и хорошее понимание сборки (см. более ранние главы).

-121--3133487-

Регулярные выражения не существуют в сборке, что кажется немного странным вопросом, поскольку Regex имеют более высокий языковой характер, он не существует на уровне гаек и болтов...

Изменить: Натан, здесь - ссылка, которая может вас заинтересовать. Прокрутите вниз до нижней части страницы;)

Надеюсь, что это поможет, С уважением, Том.

-121--3133490-

Этот фрагмент в Advanced Bash Scripting Guide говорит:

# The == comparison operator behaves differently within a double-brackets
# test than within single brackets.

[[ $a == z* ]]   # True if $a starts with a "z" (wildcard matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

Так у вас было почти правильно; нужны двойные скобки, а не одиночные скобки.


Что касается вашего второго вопроса, вы можете написать его так путь:

HOST=user1
if  [[ $HOST == user1 ]] || [[ $HOST == node* ]] ;
then
    echo yes1
fi

HOST=node001
if [[ $HOST == user1 ]] || [[ $HOST == node* ]] ;
then
    echo yes2
fi

Что будет эхо

yes1
yes2

Bash , если синтаксис трудно привыкнуть (IMO).

963
ответ дан 22 November 2019 в 21:42
поделиться

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

[ "${host#user}" != "${host}" ]

и

[ "${host#node}" != "${host}" ]

${var#expr} убирает наименьший префикс, соответствующий expr из ${var} и возвращает это. Следовательно, если ${host} не начинается с user (node), то ${host#user} (${host#node}) совпадает с ${host}.

expr позволяет fnmatch() подстановочные знаки, таким образом ${host#node??} и друзья также работают.

29
ответ дан dhke 14 January 2016 в 22:16
поделиться

Я подправил ответ @ markrushakoff, чтобы сделать его вызываемой функцией:

function yesNo {
  # prompts user with $1, returns true if response starts with y or Y or is empty string
  read -e -p "
$1 [Y/n] " YN

  [[ "$YN" == y* || "$YN" == Y* || "$YN" == "" ]]
}

Используйте это так:

$ if yesNo "asfd"; then echo "true"; else echo "false"; fi

asfd [Y/n] y
true

$ if yesNo "asfd"; then echo "true"; else echo "false"; fi

asfd [Y/n] Y
true

$ if yesNo "asfd"; then echo "true"; else echo "false"; fi

asfd [Y/n] yes
true

$ if yesNo "asfd"; then echo "true"; else echo "false"; fi

asfd [Y/n]
true

$ if yesNo "asfd"; then echo "true"; else echo "false"; fi

asfd [Y/n] n
false

$ if yesNo "asfd"; then echo "true"; else echo "false"; fi

asfd [Y/n] ddddd
false

Вот более сложная версия, которая предусматривает заданный по умолчанию значение:

function toLowerCase {
  echo "$1" | tr '[:upper:]' '[:lower:]'
}

function yesNo {
  # $1: user prompt
  # $2: default value (assumed to be Y if not specified)
  # Prompts user with $1, using default value of $2, returns true if response starts with y or Y or is empty string

  local DEFAULT=yes
  if [ "$2" ]; then local DEFAULT="$( toLowerCase "$2" )"; fi
  if [[ "$DEFAULT" == y* ]]; then
    local PROMPT="[Y/n]"
  else
    local PROMPT="[y/N]"
  fi
  read -e -p "
$1 $PROMPT " YN

  YN="$( toLowerCase "$YN" )"
  { [ "$YN" == "" ] && [[ "$PROMPT" = *Y* ]]; } || [[ "$YN" = y* ]]
}

Используйте это так:

$ if yesNo "asfd" n; then echo "true"; else echo "false"; fi

asfd [y/N]
false

$ if yesNo "asfd" n; then echo "true"; else echo "false"; fi

asfd [y/N] y
true

$ if yesNo "asfd" y; then echo "true"; else echo "false"; fi

asfd [Y/n] n
false
1
ответ дан Mike Slinn 14 January 2016 в 22:16
поделиться

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

case "$HOST" in 
    user1|node*) 
            echo "yes";;
        *)
            echo "no";;
esac

Редактировать:

Я добавил ваши чередующиеся к оператору описания выше

в вашим редактированным Версия у вас слишком много брекетов. Это должно выглядеть так:

if [[ $HOST == user1 || $HOST == node* ]];
56
ответ дан 22 November 2019 в 21:42
поделиться
-

Вы можете выбрать только часть строки, которую вы хотите проверить:

if [ "${HOST:0:4}" = user ]

для вашего последующего вопроса, вы можете использовать или :

if [[ "$HOST" == user1 || "$HOST" == node* ]]
74
ответ дан 22 November 2019 в 21:42
поделиться

@OP, как для ваших вопросов, которые вы можете использовать Case / ESAC

string="node001"
case "$string" in
  node*) echo "found";;
  * ) echo "no node";;
esac

второй вопрос

case "$HOST" in
 node*) echo "ok";;
 user) echo "ok";;
esac

case "$HOST" in
 node*|user) echo "ok";;
esac

или Bash 4.0

case "$HOST" in
 user) ;& 
 node*) echo "ok";; 
esac
8
ответ дан 22 November 2019 в 21:42
поделиться
if [ [[ $HOST == user1 ]] -o [[ $HOST == node* ]] ];  
then  
echo yes 
fi

не работает, потому что все [, [[[ и test распознают одну и ту же не рекуррсивную грамматику. см. раздел CONDITIONAL EXPRESSIONS в вашем бэш-манипуляторе.

В качестве исключения в SUSv3 сказано

Условная команда, полученная из KornShell (двойная скобка [[]]), была удалена из описания командной строки оболочки в раннем предложении. Были высказаны возражения, что реальной проблемой является неправильное использование команды test ([), и помещение ее в оболочку является неправильным способом исправления проблемы. Вместо этого достаточно соответствующей документации и нового зарезервированного слова оболочки (! ).

Тесты, требующие множественных операций test, могут быть выполнены на уровне оболочки, используя отдельные вызовы команды test и логики оболочки, а не флаг -o теста test, склонного к ошибкам.

нужно было бы написать так, но test его не поддерживает:

if [ $HOST == user1 -o $HOST == node* ];  
then  
echo yes 
fi

test использует = для равенства строк, а главное, не поддерживает совпадение по паттернам.

case / esac имеет хорошую поддержку совпадения по шаблону:

case $HOST in
user1|node*) echo yes ;;
esac

имеет дополнительное преимущество, что не зависит от bash, синтаксис переносится. из Single Unix Specification, The Shell Command Language:

case word in
    [(]pattern1) compound-list;;
    [[(]pattern[ | pattern] ... ) compound-list;;] ...
    [[(]pattern[ | pattern] ... ) compound-list]
esac
6
ответ дан 22 November 2019 в 21:42
поделиться

Если вы используете недавний Bash (V3 +), я предлагаю оператор сравнения Bash Regex = ~ , то есть

if [[ "$HOST" =~ ^user.* ]]; then
    echo "yes"
fi

, чтобы соответствовать это или что В использовании Regex | , IE

if [[ "$HOST" =~ ^user.*|^host1 ]]; then
    echo "yes"
fi

Примечание - это «правильный» синтаксис регулярного выражения.

  • Пользователь * означает использование и нулевые или больше вхождений R , поэтому используют и USERRRR Отказ
  • Пользователь. * означает Пользователь и нулевые или несколько вхождений любого символа, поэтому USER1 , USERX будет соответствовать.
  • ^ Пользователь. * означает соответствие шаблона пользователя. * на начальном $ хосте.

Если вы не знакомы с синтаксисом регулярного выражения, попробуйте со ссылкой на этот ресурс .

Примечание. Лучше, если вы запрашиваете каждый новый вопрос в качестве нового вопроса, он делает Tidier Stackoverflow и более полезным. Вы всегда можете включить ссылку на предыдущий вопрос для справки.

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

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