bash script para verificar se a entrada tem um @

2

Oi eu estou tentando escrever um script bash em que a entrada é verificada para ver se ele contém um símbolo @, eu sou relativamente novo para bash por favor perdoe qualquer / todos os erros! Até agora eu tenho:

var1="@"
var2="INPUT"

echo "input"
read INPUT

if [[ "$var2" == "$var1" ]]; then
echo "pass"
else
echo "fail"
fi
    
por JONAS402 02.11.2014 / 00:34

4 respostas

0

Este código bash lê entrada e sinaliza "Pass" se a entrada contiver um símbolo @ :

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

Notas:

  • [ "$var" ] é um teste bash. Retorna true se a string $var não estiver vazia.

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

  • Combinamos os dois acima:

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

    Este teste é bem-sucedido apenas se ${var//[^@]/} não estiver vazio e ${var//[^@]/} não estiver vazio se var contiver pelo menos um @ .

Usando um explícito if-then-else:

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

Shell 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 opção -p para read . Então, uma combinação de printf e read é usada no lugar. Além disso, faltando recursos avançados de expansão de variáveis de bash , a instrução case pode ser usada para correspondência glob.

Shell Android

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

echo -n "Input: "; read var
if ! [ "${var//@/}" = "$var" ]
then
    echo Pass
else
    echo Fail
    
por John1024 02.11.2014 / 00:51
1

Embora você tenha a opção de usar a funcionalidade de shell embutida para verificar se a entrada do usuário continha @ (o que é bem documentado nas outras respostas), outra maneira razoável de fazê-lo é com o grep utilitário:

#!/usr/bin/env bash

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

A passagem do sinal -q para grep impede a impressão de linhas correspondentes. (Ele também impede 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 reduzir o if para algo como grep -q @ <<<"$REPLY" && echo pass || echo fail , mas evitei deliberadamente:

  • Nesse caso , provavelmente está tudo bem, já que a única maneira de imprimir a palavra errada é se pass deveria ser impresso e echo não conseguiu imprimi-la. Então, presumivelmente, o eco não conseguiria imprimir fail também.
  • Embora o curto-circuito && e || sejam geralmente apropriados (e eu os uso frequentemente para abreviar uma if sem uma cláusula else ), usando-os juntos como se eles eram um operador ternário if não é realmente um bom hábito. Embora alguns comandos não possam falhar , echo pode .
  • Se o usuário redireciona a saída do seu script para um arquivo ou dispositivo não gravável, ou o usa em um quebrado pipeline , echo e outros comandos que emitem texto podem retornar falhas, causando falha na expressão && e o lado direito da expressão || para executar.
  • 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 bash:

  • -e ativa a linha de leitura 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, read coloca automaticamente a entrada do usuário na variável REPLY se nenhuma variável foi fornecida.
  • Uma string aqui com <<< é uma maneira conveniente de passar o usuário entrada para grep .
  • Bash e alguns outros shells no estilo Bourne, como traço, aceitam -p . Mas os shells compatíveis com POSIX precisam apenas entender -r . E, em alguns, como o ksh, -p tem um significado diferente.
    (Obrigado ao geirha por apontar tanto que -p às vezes está ausente e que nem sempre significa" prompt ". )

Se você quiser um script que seja portátil em outros sistemas operacionais que possam não ter o bash instalado, use:

#!/bin/sh

printf '> '
read -r line

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

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

#!/bin/sh

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

Como geirha mencionou , head -n 1 pode ser considerada uma sintaxe melhor, pois head -1 é oficialmente obsoleto (embora% atualsed implementations, ou pelo menos o GNU sed, suporta -1 em suas versões mais recentes, enquanto algumas implementações sed muito antigas não suportam -n 1 ).

Como a documentação de head diz, você pode usar sed em vez de portabilidade máxima.

#!/bin/sh

printf '> '
if sed 1q | grep -q @; then
    echo pass
else
    echo fail
fi
    
por Eliah Kagan 10.05.2015 / 22:11
0

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

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

Para scripts sh , você pode usar case .

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

Veja também o capítulo Testes e condicionais do Guia do Bash.

    
por geirha 03.11.2014 / 19:26
-1

Nas versões mais recentes do bash, você deve poder usar uma correspondência de expressão regular por meio 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 expr , por exemplo. no shell 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
$ 
    
por steeldriver 02.11.2014 / 03:46