Snaren vergelijken in Bash

Hoe vergelijk ik een variabele met een tekenreeks (en doe ik iets als ze overeenkomen)?


Antwoord 1, autoriteit 100%

Variabelen gebruiken in if-statements

if [ "$x" = "valid" ]; then
  echo "x has the value 'valid'"
fi

Als je iets wilt doen als ze niet overeenkomen, vervang dan =door !=. U kunt meer lezen over stringbewerkingenen rekenkundige bewerkingenin hun respectievelijke documentatie.

Waarom gebruiken we aanhalingstekens rond $x?

Je wilt de aanhalingstekens rond $x, want als het leeg is, komt je Bash-script een syntaxisfout tegen zoals hieronder te zien is:

if [ = "valid" ]; then

Niet-standaard gebruik van ==operator

Merk op dat Bash toestaat dat ==wordt gebruikt voor gelijkheid met [, maar dit is niet standaard.

Gebruik ofwel het eerste geval waarin de aanhalingstekens rond $xoptioneel zijn:

if [[ "$x" == "valid" ]]; then

of gebruik het tweede geval:

if [ "$x" = "valid" ]; then

Antwoord 2, autoriteit 10%

Of, als u geen else-clausule nodig heeft:

[ "$x" == "valid" ] && echo "x has the value 'valid'"

Antwoord 3, autoriteit 7%

a="abc"
b="def"
# Equality Comparison
if [ "$a" == "$b" ]; then
    echo "Strings match"
else
    echo "Strings don't match"
fi
# Lexicographic (greater than, less than) comparison.
if [ "$a" \< "$b" ]; then
    echo "$a is lexicographically smaller then $b"
elif [ "$a" \> "$b" ]; then
    echo "$b is lexicographically smaller than $a"
else
    echo "Strings are equal"
fi

Opmerkingen:

  1. Spaties tussen ifen [en ]zijn belangrijk
  2. >en <zijn omleidingsoperatoren, dus ontsnap er aan met \>en \<respectievelijk voor strings.

Antwoord 4, autoriteit 4%

Als u tekenreeksen met jokertekens wilt vergelijken, gebruikt u:

if [[ "$stringA" == *$stringB* ]]; then
  # Do something here
else
  # Do something here
fi

Antwoord 5, autoriteit 3%

Ik moet het op één punt oneens zijn met een van de opmerkingen:

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

Nee, dat is geen gekke oneliner

Het lijkt er gewoon op dat, hmm, niet-ingewijden…

Het gebruikt in zekere zin gemeenschappelijke patronen als taal;

En nadat je de taal hebt geleerd.

Eigenlijk is het leuk om te lezen

Het is een eenvoudige logische uitdrukking, met één speciaal onderdeel: luie evaluatie van de logische operatoren.

[ "$x" == "valid" ] && echo "valid" || echo "invalid"

Elk deel is een logische uitdrukking; de eerste kan waar of onwaar zijn, de andere twee zijn altijd waar.

(
[ "$x" == "valid" ] 
&&
echo "valid"
)
||
echo "invalid"

Nu, wanneer het wordt geëvalueerd, wordt de eerste gecontroleerd. Als het onwaar is, dan is de tweede operand van de logica en&&erna niet relevant. Het eerste is niet waar, dus het kan niet het eerste zijn en het tweede kan sowieso niet waar zijn.
In dit geval is de eerste kant van de logica of||false, maar het zou waar kunnen zijn als de andere kant – de derde deel – is waar.

Dus het derde deel zal worden geëvalueerd – voornamelijk het bericht schrijven als bijwerking. (Het heeft het resultaat 0voor true, wat we hier niet gebruiken)

De andere gevallen zijn vergelijkbaar, maar eenvoudiger – en – dat beloof ik! zijn – kunnen – gemakkelijk te lezen zijn!
(Ik heb er geen, maar ik denk dat een UNIX-veteraan met grijze baard hier veel bij helpt.)


Antwoord 6, autoriteit 2%

Het volgende script leest regel voor regel uit een bestand met de naam “testonthis” en vergelijkt vervolgens elke regel met een eenvoudige tekenreeks, een tekenreeks met speciale tekens en een reguliere expressie. Als het niet overeenkomt, zal het script de regel afdrukken, anders niet.

Ruimte in Bash is zo belangrijk. Dus het volgende zal werken:

[ "$LINE" != "table_name" ] 

Maar het volgende niet:

["$LINE" != "table_name"] 

Dus gebruik zoals het is:

cat testonthis | while read LINE
do
if [ "$LINE" != "table_name" ] && [ "$LINE" != "--------------------------------" ] && [[ "$LINE" =~ [^[:space:]] ]] && [[ "$LINE" != SQL* ]]; then
echo $LINE
fi
done

Antwoord 7, autoriteit 2%

U kunt ook case/esacgebruiken:

case "$string" in
 "$pattern" ) echo "found";;
esac

Antwoord 8

Ik zou waarschijnlijk regexp-overeenkomsten gebruiken als de invoer slechts een paar geldige vermeldingen heeft. bijv. alleen de “start” en “stop” zijn geldige acties.

if [[ "${ACTION,,}" =~ ^(start|stop)$ ]]; then
  echo "valid action"
fi

Merk op dat ik de variabele $ACTIONkleine letters gebruik door dubbele komma’s te gebruiken. Merk ook op dat dit niet werkt op te oude bash-versies die er zijn.


Antwoord 9

Bash 4+ voorbeelden. Opmerking: het niet gebruiken van aanhalingstekens zal problemen veroorzaken wanneer woorden spaties bevatten, enz. Citeer altijd in Bash, IMO.

Hier zijn enkele voorbeelden in Bash 4+:

Voorbeeld 1, controleer op ‘ja’ in tekenreeks (hoofdletterongevoelig):

   if [[ "${str,,}" == *"yes"* ]] ;then

Voorbeeld 2, controleer op ‘ja’ in tekenreeks (hoofdletterongevoelig):

   if [[ "$(echo "$str" | tr '[:upper:]' '[:lower:]')" == *"yes"* ]] ;then

Voorbeeld 3, controleer op ‘ja’ in tekenreeks (hoofdlettergevoelig):

    if [[ "${str}" == *"yes"* ]] ;then

Voorbeeld 4, controleer op ‘ja’ in tekenreeks (hoofdlettergevoelig):

    if [[ "${str}" =~ "yes" ]] ;then

Voorbeeld 5, exacte overeenkomst (hoofdlettergevoelig):

    if [[ "${str}" == "yes" ]] ;then

Voorbeeld 6, exacte overeenkomst (niet hoofdlettergevoelig):

    if [[ "${str,,}" == "yes" ]] ;then

Voorbeeld 7, exacte overeenkomst:

    if [ "$a" = "$b" ] ;then

Veel plezier.


Antwoord 10

Ik deed het op deze manier die compatibel is met Bash en Dash(sh):

testOutput="my test"
pattern="my"
case $testOutput in (*"$pattern"*)
    echo "if there is a match"
    exit 1
    ;;
(*)
   ! echo there is no coincidence!
;;esac

Antwoord 11

Heeft u vergelijkingsproblemen? (zoals hieronder?)

var="true"
if [[ $var == "true" ]];then
  #should be working but it is not....
else
  #it is falling here...
fi

Probeer de operator =~(operator voor reguliere expressies) en het zou kunnen werken:

var="true"
if [[ $var =~ "true" ]];then
  #now it works here!!
else
  #no more inequality 
fi

Other episodes