ist. Ich suche nach einem Konstrukt in bash
, um zu entscheiden, ob Eine Variable $WORD
ist eines der definierten Wörter. Ich brauche so etwas:
if "$WORD" in dog cat horse ; then echo yes else echo no fi
hat bash ein solches Konstrukt? Wenn nicht, welche wäre die nächste?
Antwort
Dies ist eine reine Bash-Lösung (> = Version 3) verwendet reguläre Ausdrücke:
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 behoben werden durch:
sed "s/[[:blank:]]//g" /your/file | paste -sd "|" /dev/stdin
Vielen Dank an @terdon, der mich daran erinnert hat, das Muster ordnungsgemäß mit ^
und $
.
Kommentare
- Und
shopt -s nocasematch
kann hilfreich sein, wenn bei der Suche die Groß- und Kleinschreibung nicht berücksichtigt werden soll. - Beachten Sie, dass Sie
[[
und]]
–[
und]
reichen nicht aus. - Ich habe gesucht für einen ‚ Oneliner ‚, um mein Skriptargument zu validieren, und dies funktionierte perfekt. Danke!
[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
- Wenn Sie ‚ Ihre Liste der Übereinstimmungen in eine Datei einfügen möchten, können Sie diese auch verwenden grep:
egrep -q "^$WORD$" /tmp/words; [[ $? != 0 ]] && echo "Not found" || echo "OK"
.
Antwort
case $word in dog|cat|horse) echo yes;; *) echo no;; esac
Antwort
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
Antwort
if (echo "$set" | fgrep -q "$WORD")
Kommentare
- Vorsicht, dies gibt true zurück, wenn
$WORD
leer ist, stimmt es überein, wennWORD=ca
oderWORD=og
oder ähnliches und ich nehme an, Sie meintenecho ${set[@]}
. - fügen Sie einfach hinzu -w zu grep, um Teilwörter zu vermeiden
Antwort
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 }
Verwenden Sie dann einfach Folgendes:
word_valid cat
Antwort
Ich suchte nach einer „einzeiligen“ Lösung, um mein Skriptargument zu validieren, und verwendete oben die Antwort Joseph R. up with:
[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
Antwort
Sie Mit fgrep können alle zulässigen Wörter angegeben werden:
if $(echo "$WORD" | fgrep -wq -e dog -e cat -e horse) ; then echo yes else echo no fi
Das Flag -w
stimmt nur mit vollständigen Wörtern überein, das -q
bewirkt, dass es unbeaufsichtigt arbeitet (da wir nur den Rückgabewert für die zu verwendende if-Anweisung benötigen), und jedes -e
-Muster gibt ein Muster an
fgrep
ist die Version von grep, die normale Zeichenfolgenübereinstimmung anstelle von Regex-Übereinstimmungen ausführt. Wenn Sie grep
haben, sollten Sie fgrep
haben. Wenn nicht, ist dies identisch mit der Verwendung von grep
durch das Flag -F
(Sie würden also einfach fgrep -wq
oben durch grep -Fwq
).
Antwort
Dies 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
Antwort
Möglicherweise möchten Sie die Liste der Wörter in eine Datei einfügen, falls Sie die Liste häufig ändern oder möchten 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 können Sie
if fgrep –qx "$WORD" word_list
- Nein, ich ‚ möchte meine Liste nicht in einer Datei haben
Antwort
Wenn Wörter eine Liste sind, in der 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
Antwort
Ich hatte gerade das gleiche Problem und fand eine überraschend verständliche Lösung, für die keine Regex-Kenntnisse erforderlich sind.
Bitte beachten Sie, dass die Die unten gezeigte Lösung ist möglicherweise nur Bash, da ich keine Ahnung habe, welche Unterschiede zwischen Bash und anderen Shells bestehen. Darüber hinaus warnt das Bash-Handbuch, dass diese Art der Musterübereinstimmung langsam ist, wenn die Zeichenfolge, die abgeglichen werden soll, lang ist.
WORD=abc [[ "$WORD" == @(def|abc|ghi|foo|barbaz) ]] && echo Word is in set.
Wie funktioniert das?Ich möchte hier keine großen Teile des Bash-Handbuchs wiederholen, aber in meinen eigenen Worten:
Wenn der binäre Operator ==
mit dem zusammengesetzten Befehl verwendet wird [[
, das Wort auf der rechten Seite des Operators wird einem Mustervergleich unterzogen, wie im Abschnitt “ Mustervergleich im Bash-Handbuch. Außerdem wird unter diesen Bedingungen beim Matching angenommen, dass die Shell-Option extglob
festgelegt ist (unabhängig von der tatsächlichen Einstellung) Der entscheidende Punkt für das Verständnis des oben Gesagten.
Aber was ist, wenn die Wörter in Ihrem Satz bereits Zeichen enthalten, die eine besondere Bedeutung für den Mustervergleich, die Befehlssubstitution und andere Erweiterungen haben? Das Mittel ist einfach: Verwenden Sie einfach so etwas wie
[[ "$WORD" == @("a*"|abc|"?ghi"|"$DontExpandMe"|barbaz) ]] && echo Word is in set.
Ich fand das sehr einfach, verständlich und effizient (solange $WORD
kurz ist) Lösung, die keine Nebenwirkungen hat oder da ist wie die set
-basierten Methoden.