script bash para verificar se a entrada tem um @

script bash para verificar se a entrada tem um @

Olá, estou tentando escrever um script bash no qual a entrada é verificada para ver se contém um símbolo @. Sou relativamente novo no bash, então perdoe todos/todos os erros! Até agora eu tenho:

var1="@"
var2="INPUT"

echo "input"
read INPUT

if [[ "$var2" == "$var1" ]]; then
echo "pass"
else
echo "fail"
fi

Responder1

Embora você tenha a opção de usar a funcionalidade interna do shell para verificar se a entrada do usuário está contida @(o que está bem documentado nas outras respostas), outra maneira razoável de fazer isso é com o externogrepUtilitário:

#!/usr/bin/env bash

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

Passar o -qsinalizador para grepevita a impressão de linhas correspondentes. (Também evita que ele leia mais linhas depois de encontrar uma correspondência, mas isso não faz diferença aqui, pois há apenas uma linha de entrada.)

É tentador encurtar a ifconstrução para algo como grep -q @ <<<"$REPLY" && echo pass || echo fail, mas evitei deliberadamente fazer isso:

  • Nesse caso, provavelmente está tudo bem, já que a única maneira de a palavra errada ser impressa é se passdeveria ser impressa e echonão foi impressa. Então, presumivelmente, echo failtambém não seria impresso .
  • Embora curto-circuito &&e ||muitas vezes sejam apropriados (e eu os uso frequentemente para abreviar umif semuma elsecláusula), usando-os juntos como se fossemum ternárioseoperadornão é realmente um bom hábito. Embora alguns comandos não possamfalhar,echo pode.
  • Se o usuárioredirecionamentosa saída do seu script para um arquivo ou dispositivo não gravável, ou usa-o de forma quebradagasoduto, echo e outros comandos que geram texto podem retornar falha, fazendo com que a &&expressão falhe e o lado direito da ||expressão seja executado.
  • Você pode testar o comportamento de um script na presença de um dispositivo de saída não gravável executando-o com >/dev/full.

Esse script usa alguns recursos do bash:

  • -ehabilita o readline GNU, para que o usuário possa mover o cursor para a esquerda e para a direita com as teclas de seta para editar sua entrada ao inseri-la.
  • No bash, readcoloca automaticamente a entrada do usuário na REPLYvariável se nenhuma variável for fornecida.
  • Aaqui stringwith <<<é uma maneira conveniente de passar a entrada do usuário para grep.
  • Bash ealgunsoutros shells no estilo Bourne, como dash, aceitam -p. MasShells compatíveis com POSIX precisam apenas entender-r. E em alguns, como ksh, -ptem um significado diferente.
    (Graças ageirhapor apontar tanto isso-pàs vezes está ausentee essanem sempre significa "rápido".)

Se você deseja um script portátil para outros sistemas operacionais que talvez não tenham o bash instalado, você pode usar:

#!/bin/sh

printf '> '
read -r line

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

Se desejar, você pode pular o armazenamento da entrada do usuário em uma variável lendo-a comheadem vez de read:

#!/bin/sh

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

ComoGeirha mencionou, head -n 1pode ser considerada uma sintaxe melhor como head -1éoficialmente obsoleto(embora as implementações atuais sed, ou pelo menos o GNU sed, suportem -1suas versões mais recentes, enquanto algumas sedimplementações muito antigas não suportam -n 1).

Comoa headdocumentaçãodiz, você pode usar sedem vez disso para máxima portabilidade.

#!/bin/sh

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

Responder2

Este bashcódigo lê a entrada e sinaliza "Aprovado" se a entrada contiver um @símbolo:

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

Notas:

  • [ "$var" ]é um teste bash. Ele retorna verdadeiro se a string $varnão estiver vazia.

  • Um dos recursos do bash é a substituição de padrões. Parece ${var//pattern/string}. Ele substitui todas as ocorrências de patternin varpor string. No nosso caso, patterné [^@]uma expressão regular que corresponde a todos os caracteresexceto @. Assim, ${var//[^@]/}retorna uma string vazia, a menos que varcontenha pelo menos um @.

  • Combinamos os dois acima:

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

    Este teste será bem-sucedido somente se ${var//[^@]/}não estiver vazio e ${var//[^@]/}não estiver vazio somente se varcontiver pelo menos um @.

Usando um if-then-else explícito:

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

Concha POSIX

O seguinte funciona em dash( /bin/sh) e deve funcionar em qualquer shell POSIX:

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

O shell POSIX não suporta a -popção deread. Portanto, uma combinação de printfe readé usada. Além disso, na falta de recursos avançados de expansão de variáveis bash, a caseinstrução pode ser usada para correspondência glob.

Concha Android

Usando o shell padrão no meu Android, funciona o seguinte:

echo -n "Input: "; read var
if ! [ "${var//@/}" = "$var" ]
then
    echo Pass
else
    echo Fail

Responder3

A maneira preferida no bash é usar o recurso de correspondência de padrões do [[ ... ]].

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

Para shscripts, você pode usar case.

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

Veja também oTestes e Condicionaiscapítulo do Guia Bash.

Responder4

Nas versões mais recentes do bash, você poderá usar umcorrespondência de expressão regularatravés do =~operador de teste estendido:

$ 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

Uma alternativa que deve funcionar em qualquer sistema compatível com POSIX é usar, exprpor exemplo, no dashshell:

$ 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
$ 

informação relacionada