Hallo, ich versuche, ein Bash-Skript zu schreiben, in dem die Eingabe überprüft wird, um festzustellen, ob sie ein @-Symbol enthält. Ich bin relativ neu bei Bash, also verzeihen Sie mir bitte alle Fehler! Bisher habe ich:
var1="@"
var2="INPUT"
echo "input"
read INPUT
if [[ "$var2" == "$var1" ]]; then
echo "pass"
else
echo "fail"
fi
Antwort1
Obwohl Sie die Möglichkeit haben, die eingebaute Shell-Funktionalität zu verwenden, um zu prüfen, ob die Eingabe des Benutzers enthalten ist @
(was in den anderen Antworten gut dokumentiert ist), ist eine andere sinnvolle Möglichkeit, dies zu tun, die externegrep
Dienstprogramm:
#!/usr/bin/env bash
read -erp '> '
if grep -q @ <<<"$REPLY"; then
echo pass
else
echo fail
fi
Durch Übergeben des -q
Flags grep
wird verhindert, dass übereinstimmende Zeilen gedruckt werden. (Es verhindert auch, dass nach dem Finden einer Übereinstimmung weitere Zeilen gelesen werden, aber das macht hier keinen Unterschied, da nur eine Eingabezeile vorhanden ist.)
if
Es ist verlockend, die Konstruktion auf etwas wie abzukürzen grep -q @ <<<"$REPLY" && echo pass || echo fail
, aber ich habe dies bewusst vermieden:
- In diesem Fall, das ist wahrscheinlich in Ordnung, da das falsche Wort nur dann gedruckt wird, wenn es
pass
eigentlich gedruckt werden sollte undecho
nicht gedruckt wurde. Dann würde vermutlichfail
auch echo nicht gedruckt. - Während Kurzschluss
&&
und||
oft selbst angemessen sind (und ich benutze sie häufig, um einenif
ohneeineelse
Klausel), wobei sie zusammen verwendet werden, als obein ternäresWennOperatorist nicht wirklich eine gute Angewohnheit. Während einige Befehle nichtscheitern,echo
dürfen. - Wenn der BenutzerWeiterleitungendie Ausgabe Ihres Skripts in eine nicht beschreibbare Datei oder auf ein nicht beschreibbares Gerät oder verwendet es in einem defektenPipeline, Echo und andere Befehle, die Text ausgeben, können Fehler zurückgeben, wodurch der
&&
Ausdruck fehlschlägt und die rechte Seite des||
Ausdrucks ausgeführt wird. - Sie können das Verhalten eines Skripts bei Vorhandensein eines nicht beschreibbaren Ausgabegeräts testen, indem Sie es mit ausführen
>/dev/full
.
Dieses Skript verwendet einige Bash-Funktionen:
-e
aktiviert GNU Readline, sodass der Benutzer den Cursor mit den Pfeiltasten nach links und rechts bewegen kann, um seine Eingabe während der Eingabe zu bearbeiten.- In Bash
read
wird die Benutzereingabe automatisch in dieREPLY
Variable eingefügt, wenn keine Variable angegeben wurde. - Ahier Zeichenfolgemit
<<<
ist eine praktische Möglichkeit, die Benutzereingaben an weiterzuleitengrep
. - Bash undmancheandere Shells im Bourne-Stil wie dash accept
-p
. AberPOSIX-kompatible Shells müssen nur verstehen-r
. Und in manchen Fällen, wie zum Beispiel ksh,-p
hat es eine andere Bedeutung.
(Danke angeirhafür den Hinweis, dass-p
fehlt manchmalund dasEs bedeutet nicht immer „prompt“.)
Wenn Sie ein Skript wünschen, das auf andere Betriebssysteme portierbar ist, auf denen Bash möglicherweise nicht installiert ist, können Sie Folgendes verwenden:
#!/bin/sh
printf '> '
read -r line
if printf '%s' "$line" | grep -q @; then
echo pass
else
echo fail
fi
Wenn Sie möchten, können Sie das Speichern der Benutzereingaben in einer Variablen überspringen, indem Sie sie mithead
anstatt read
:
#!/bin/sh
printf '> '
if head -1 | grep -q @; then
echo pass
else
echo fail
fi
AlsGeirha erwähnt, head -n 1
könnte als bessere Syntax angesehen werden, wie head -1
sie istoffiziell veraltet(obwohl aktuelle sed
Implementierungen oder zumindest GNU sed -1
in ihren neuesten Versionen dies unterstützen, während einige sehr alte sed
Implementierungen dies nicht unterstützen -n 1
).
Alsdie head
Dokumentationsagt, Sie können sed
stattdessen für maximale Portabilität verwenden.
#!/bin/sh
printf '> '
if sed 1q | grep -q @; then
echo pass
else
echo fail
fi
Antwort2
Dieser bash
Code liest die Eingabe und signalisiert „Pass“, wenn die Eingabe ein @
Symbol enthält:
read -p "Input: " var
[ "${var//[^@]/}" ] && echo Pass || echo Fail
Anmerkungen:
[ "$var" ]
ist ein Bash-Test. Er gibt „true“ zurück, wenn die Zeichenfolge$var
nicht leer ist.Eine der Funktionen von Bash ist die Musterersetzung. Es sieht aus wie
${var//pattern/string}
. Es ersetzt jedes Vorkommen vonpattern
invar
durchstring
. In unserem Fallpattern
ist[^@]
dies ein regulärer Ausdruck, der auf jedes Zeichen passtaußer@
. Gibt daher${var//[^@]/}
einen leeren String zurück, sofern nichtvar
mindestens ein enthalten ist@
.Wir kombinieren die beiden oben genannten:
[ "${var//[^@]/}" ]
Dieser Test ist nur erfolgreich, wenn
${var//[^@]/}
nicht leer ist, und${var//[^@]/}
nur dann nicht leer, wennvar
mindestens ein enthält@
.
Verwenden eines expliziten if-then-else:
read -p "Input: " var
if [ "${var//[^@]/}" ]
then
echo Pass
else
echo Fail
fi
POSIX-Shell
Folgendes funktioniert unter dash
( /bin/sh
) und sollte unter jeder POSIX-Shell funktionieren:
printf "Input: "
read var
case "$var" in
*@*) echo Pass
;;
*) echo Fail
;;
esac
Die POSIX-Shell unterstützt nicht die -p
Option,read
. Stattdessen wird also eine Kombination aus printf
und read
verwendet. Da außerdem die erweiterten Variablenerweiterungsfunktionen von fehlen , kann bash
die Anweisung für Glob-Matching verwendet werden.case
Android Shell
Mit der Standard-Shell auf meinem Android funktioniert Folgendes:
echo -n "Input: "; read var
if ! [ "${var//@/}" = "$var" ]
then
echo Pass
else
echo Fail
Antwort3
In Bash wird die Mustervergleichsfunktion von bevorzugt [[ ... ]]
.
#bash
read -rp "Input: " input
if [[ $input = *@* ]]; then
printf '<%s> contains @\n' "$input"
fi
Für sh
Skripte können Sie case
stattdessen verwenden.
#sh
printf 'Input: '
read -r input
case $input in
*@*) printf '<%s> contains @\n' "$input" ;;
esac
Siehe auch dieTests und BedingungenKapitel des Bash-Handbuchs.
Antwort4
In neueren Versionen von Bash sollten Sie in der Lage sein, einenÜbereinstimmung mit regulären Ausdrückenüber den =~
erweiterten Testoperator:
$ 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
Eine Alternative, die in jedem POSIX-kompatiblen System funktionieren sollte, ist expr
beispielsweise die Verwendung in der dash
Shell:
$ 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
$