сценарий удара, чтобы проверить, имеет ли введенный

Привет я пытаюсь записать сценарий удара, в котором вход проверяется, чтобы видеть, содержит ли он символ, я, является относительно новым для избиения, поэтому простите любые/все ошибки! До сих пор я имею:

var1="@"
var2="INPUT"

echo "input"
read INPUT

if [[ "$var2" == "$var1" ]]; then
echo "pass"
else
echo "fail"
fi
2
задан 2 November 2014 в 03:22

4 ответа

Это bash кодируйте вход чтений и сигналы "Передача", если вход содержит @ символ:

read -p "Input: " var
[ "${var//[^@]/}" ] && echo Pass || echo Fail

Примечания:

  • [ "$var" ] тест удара. Это возвращает true если строка $var непусто.

  • Одной из функций удара является замена шаблона. Это похоже ${var//pattern/string}. Это заменяет каждое возникновение pattern в var с string. В нашем случае, pattern [^@] который является регулярным выражением, которое соответствует каждому символу кроме @. Таким образом ${var//[^@]/} возвращает пустую строку если var содержит по крайней мере один @.

  • Мы комбинируем вышеупомянутые два:

    [ "${var//[^@]/}" ]
    

    Этот тест успешно выполняется только если ${var//[^@]/} непусто и ${var//[^@]/} непусто только если var содержит по крайней мере один @.

Используя явный if-then-else:

read -p "Input: " var
if [ "${var//[^@]/}" ]
then
    echo Pass
else
    echo Fail
fi

POSIX Shell

Следующие работы под dash (/bin/sh) и должен работать под любой оболочкой POSIX:

printf "Input: "
read var
case "$var" in
    *@*) echo Pass
        ;;
    *) echo Fail
        ;;
esac

Оболочка POSIX не поддерживает -p опция к read. Так, комбинация printf и read используются вместо этого. Кроме того, испытывая недостаток в усовершенствованных переменных функциях расширения bash, case оператор может использоваться для соответствия шарика.

Android Shell

Используя оболочку по умолчанию на моем андроиде, следующих работах:

echo -n "Input: "; read var
if ! [ "${var//@/}" = "$var" ]
then
    echo Pass
else
    echo Fail
0
ответ дан 10 November 2019 в 04:49

Хотя у Вас есть опция использования встроенной функциональности оболочки, чтобы проверить, содержал ли вход пользователя @ (который хорошо документируется в другие ответы), другой разумный способ сделать это с внешним grep утилита:

#!/usr/bin/env bash

read -erp '> '
if grep -q @ <<<"$REPLY"; then
    echo pass
else
    echo fail
fi

Передача -q флаг к grep предотвращает его печатающий согласующие отрезки длинной линии. (Это также мешает ему читать больше строки после нахождения соответствия, но это не имеет значения здесь, поскольку существует только одна строка входа.)

Заманчиво сократиться if создайте к чему-то как grep -q @ <<<"$REPLY" && echo pass || echo fail, но я сознательно постарался не делать так:

  • В этом случае это, вероятно, хорошо, так как единственный способ, которым печатает неправильное слово, состоит в том если pass как предполагалось, был распечатан и echo не удалось распечатать его. Затем по-видимому, эху не удалось бы распечатать fail также.
  • В то время как короткое замыкание && и || являются часто самостоятельно соответствующими (и я часто использую их для сокращения if без else пункт), с помощью них вместе, как будто они были троичным, если оператор не является действительно хорошей привычкой. В то время как некоторые команды не могут перестать работать, echo может.
  • Если пользователь перенаправляет вывод Вашего сценария в неперезаписываемый файл или устройство, или использует его в поврежденном конвейере, эхе и других командах, которые синтезируемый текст может возвратить отказ, вызвав && выражение для сбоя и правая сторона || выражение для выполнения.
  • Можно протестировать поведение сценария в присутствии неперезаписываемого устройства вывода путем выполнения его с >/dev/full.

Тот сценарий использует несколько функций удара:

Если Вы хотите сценарий, это портативно к на других Ose, которые не могли бы иметь установленного удара, можно использовать:

#!/bin/sh

printf '> '
read -r line

if printf '%s' "$line" | grep -q @; then
    echo pass
else
    echo fail
fi

Если Вам нравится, можно пропустить хранение входа пользователя в переменной путем чтения его с head вместо read:

#!/bin/sh

printf '> '
if head -1 | grep -q @; then
    echo pass
else
    echo fail
fi

Как geirha упомянутый, head -n 1 мог бы считаться лучшим синтаксисом как head -1 является официально устаревшим (хотя текущий sed реализации, или по крайней мере GNU sed, поддержка -1 в их последних версиях, в то время как некоторые очень старые sed реализации не поддерживают -n 1).

Как head в документации говорится, можно использовать sed вместо этого для максимальной мобильности.

#!/bin/sh

printf '> '
if sed 1q | grep -q @; then
    echo pass
else
    echo fail
fi
1
ответ дан 10 November 2019 в 04:49

Предпочтительный путь в ударе состоит в том, чтобы использовать функцию сопоставления с образцом [[ ... ]].

#bash
read -rp "Input: " input
if [[ $input = *@* ]]; then
    printf '<%s> contains @\n' "$input"
fi

Для sh сценарии можно использовать case вместо этого.

#sh
printf 'Input: '
read -r input
case $input in
    *@*) printf '<%s> contains @\n' "$input" ;;
esac

См. также Тесты и Условные выражения глава Руководства Bash.

0
ответ дан 10 November 2019 в 04:49

В более новых версиях удара необходимо быть в состоянии использовать соответствие регулярного выражения через =~ расширенный тестовый оператор:

$ read -p "input: " input
input: quertyuiop 
$ if [[ $input =~ \@ ]]; then echo "match"; else echo "no match"; fi
no match
$ 
$ read -p "input: " input
input: qwerty@uiop
$ if [[ $input =~ \@ ]]; then echo "match"; else echo "no match"; fi
match

альтернатива, которая должна работать в любом POSIX совместимая система, должна использовать expr, например, в эти dash оболочка:

$ read input
qwertyuiop
$ if expr "$input" : '.*@.*' > /dev/null; then echo 'match'; else echo 'no match'; fi
no match
$ 
$ read input
qwerty@uiop
$ if expr "$input" : '.*@.*' > /dev/null; then echo 'match'; else echo 'no match'; fi
match
$ 
-1
ответ дан 10 November 2019 в 04:49

Другие вопросы по тегам:

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