bash: teste ob $ WORD gesetzt ist

54

Ich suche ein Konstrukt in bash, um zu entscheiden, ob eine Variable $WORDeines von definierten Wörtern ist. Ich brauche so etwas:

if "$WORD" in dog cat horse ; then 
    echo yes
else
    echo no
fi

Hat Bash ein solches Konstrukt? Wenn nicht, welches wäre das nächste?

Martin Vegter
quelle

Antworten:

57

Dies ist eine reine Bash-Lösung (> = Version 3), die reguläre Ausdrücke verwendet:

if [[ "$WORD" =~ ^(cat|dog|horse)$ ]]; then
    echo "$WORD is in the list"
else
    echo "$WORD is not in the list"
fi

Wenn Ihre Wortliste lang ist, können Sie sie in einer Datei speichern (ein Wort pro Zeile) und dies tun:

if [[ "$WORD" =~ $(echo ^\($(paste -sd'|' /your/file)\)$) ]]; then
    echo "$WORD is in the list"
else
    echo "$WORD is not in the list"
fi

Eine Einschränkung beim Dateiansatz:

  • Es wird unterbrochen, wenn die Datei Leerzeichen enthält. Dies kann durch Folgendes behoben werden:

    sed 's/[[:blank:]]//g' /your/file | paste -sd '|' /dev/stdin

Vielen Dank an @terdon, der mich daran erinnert hat, das Muster mit ^und richtig zu verankern $.

Joseph R.
quelle
1
Und shopt -s nocasematchkann hilfreich sein, wenn bei der Suche die Groß- und Kleinschreibung nicht berücksichtigt werden soll.
Skippy le Grand Gourou
1
Beachten Sie, dass Sie [[und verwenden müssen ]]- [und ]nicht genug sind.
Greg Dubicki
Ich war auf der Suche nach einem "Oneliner", um mein Skriptargument zu validieren, und das funktionierte perfekt. Dankeschön! [[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
RASG
76
case $word in
    dog|cat|horse) echo yes;;
    *)             echo no;;
esac
John Kugelman unterstützt Monica
quelle
11

Wie wäre es mit:

#!/usr/bin/env bash

WORD="$1"
for w in dog cat horse
do
  if [ "$w" == "$WORD" ] 
  then
      yes=1
      break
  fi
done;
[ "$yes" == "1" ] && echo "$WORD is in the list" || 
                     echo "$WORD is not in the list"

Dann:

$ a.sh cat
cat is in the list
$ a.sh bob
bob is not in the list
terdon
quelle
3
if (echo "$set"  | fgrep -q "$WORD")
BrenoZan
quelle
1
Aber Vorsicht, das wahr zurück, wenn $WORDleer, wird es passen , wenn WORD=caoder WORD=ogoder ähnlich , und ich nehme an, Sie gemeint echo ${set[@]}.
Terdon
Füge
1

Sie können hierfür eine Bash-Funktion definieren:

function word_valid() 
{ 
  if [ "$1" != "cat" -a "$1" != "dog" -a "$1" != "horse" ];then
    echo no
  else
    echo yes
  fi
}

Dann benutze einfach so:

word_valid cat
Verdächtiger
quelle
1

Ich suchte nach einer "einzeiligen" Lösung, um mein Skriptargument zu validieren, und benutzte Joseph Rs obige Antwort , um Folgendes zu finden:

[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }

RASG
quelle
0

Das hat bei mir funktioniert:

#!/bin/bash
phrase=(cat dog parrot cow horse)
findthis=parrot

for item in ${phrase[*]}
do
    test "$item" == "$findthis" && { echo "$findthis found!"; break; }
done
Javier
quelle
0

Möglicherweise möchten Sie die Wortliste in eine Datei einfügen, falls Sie die Liste häufig ändern, oder möchten, dass sie von mehreren Skripten gemeinsam genutzt wird. Und Sie müssen die Wörter möglicherweise in eine Datei einfügen, wenn die Liste zu lang wird, um sie in einem Skript zu verwalten. Dann kannst du sagen

if fgrep qx "$WORD" word_list
Scott
quelle
nein, ich möchte meine Liste nicht in einer Datei haben
Martin Vegter
0

Wenn es sich bei Wörtern um eine Liste handelt, bei der die Werte durch einen Zeilenumbruch getrennt sind, können Sie Folgendes tun:

WORDS="$(ls -1)"
if echo "${WORDS}" | grep --quiet --line-regexp --fixed-strings "${WORD}"; then
    echo yes
else
    echo no
fi
Mitar
quelle
0

Sie können fgrep verwenden, um alle zulässigen Wörter anzugeben:

if $(echo "$WORD" | fgrep -wq -e dog -e cat -e horse) ; then 
    echo yes
else
    echo no
fi

Das -wFlag stimmt nur mit vollständigen Wörtern überein, das -qFlag bewirkt, dass es im Hintergrund ausgeführt wird (alles, was wir benötigen, ist der Rückgabewert für die zu verwendende if-Anweisung), und jedes -eMuster gibt ein zuzulassendes Muster an.

fgrepist die Version von grep, die den normalen String-Abgleich anstelle des Regex-Abgleichs vornimmt. Wenn Sie haben grep, sollten Sie haben fgrep, aber wenn nicht, ist es identisch mit der Verwendung grepmit der -FFlagge (so würden Sie nur fgrep -wqoben mit ersetzen grep -Fwq).

Christopher Shroba
quelle