bash: sprawdź, czy $ WORD jest ustawiony

54

Szukam konstrukcji w bash, aby zdecydować, czy zmienna $WORDjest jednym ze zdefiniowanych słów. Potrzebuję czegoś takiego:

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

czy bash ma taką konstrukcję? Jeśli nie, co byłoby najbliższe?

Martin Vegter
źródło

Odpowiedzi:

57

Jest to rozwiązanie tylko dla Bash (> = wersja 3), które wykorzystuje wyrażenia regularne:

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

Jeśli lista słów jest długa, możesz zapisać ją w pliku (jedno słowo w wierszu) i zrobić to:

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

Jedno zastrzeżenie dotyczące podejścia do plików:

  • Zepsuje się, jeśli plik będzie zawierał spacje. Można temu zaradzić poprzez:

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

Dzięki @terdon za przypomnienie, żebym poprawnie zakotwiczył wzór za pomocą ^i $.

Joseph R.
źródło
1
I shopt -s nocasematchmoże pomóc, jeśli chcesz, aby wyszukiwanie nie uwzględniało wielkości liter.
Skippy le Grand Gourou
1
Pamiętaj, że musisz użyć [[i ]]- [i ]nie wystarczy.
Greg Dubicki
szukałem „onelinera”, aby zweryfikować mój argument skryptu, i działało to doskonale. Dziękuję Ci! [[ "$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 wspiera Monikę
źródło
11

Co powiesz na:

#!/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"

Następnie:

$ a.sh cat
cat is in the list
$ a.sh bob
bob is not in the list
terdon
źródło
3
if (echo "$set"  | fgrep -q "$WORD")
BrenoZan
źródło
1
Uważaj jednak, będzie to powrót true, jeśli $WORDjest pusta, jeśli będzie on pasował WORD=calub WORD=ogczy podobne i zakładam, że rozumie echo ${set[@]}.
terdon
wystarczy dodać -w do grep, aby uniknąć częściowych słów
BrenoZan
1

Możesz dla tego zdefiniować funkcję bash:

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

Następnie użyj po prostu tak:

word_valid cat
podejrzenie
źródło
1

szukałem rozwiązania „jednego wiersza”, aby zweryfikować mój argument skryptu, i użyłem odpowiedzi Josepha R. powyżej, aby wymyślić:

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

RASG
źródło
0

To działało dla mnie:

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

for item in ${phrase[*]}
do
    test "$item" == "$findthis" && { echo "$findthis found!"; break; }
done
Javier
źródło
0

Możesz umieścić listę słów w pliku, na wypadek częstej zmiany listy lub udostępniania wielu skryptów. I może być konieczne wstawienie słów do pliku, jeśli lista jest zbyt długa, aby zarządzać nią w skrypcie. Więc możesz powiedzieć

if fgrep qx "$WORD" word_list
Scott
źródło
nie, nie chcę mieć mojej listy w pliku
Martin Vegter 30.01.2014
0

Jeśli słowa są listą, na której wartości są oddzielone znakiem nowej linii, możesz:

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

Możesz użyć fgrep, aby określić wszystkie dozwolone słowa:

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

-wFlaga pasuje tylko pełne słowa, -qflag sprawia, że działają cicho (bo wszystko czego potrzebujemy to wartość zwracana przez if używać), a każdy -ewzór określa wzór, aby umożliwić.

fgrepto wersja grep, która wykonuje normalne dopasowywanie ciągów zamiast dopasowywania wyrażeń regularnych. Jeśli tak grep, powinieneś to zrobić fgrep, ale jeśli nie, to identyczne jak używanie grepz -Fflagą (więc po prostu zastąpiłbyś fgrep -wqpowyżej grep -Fwq).

Christopher Shroba
źródło