web-dev-qa-db-fra.com

bash: teste si $ Word est dans l'ensemble

Je cherche une construction dans bash, pour décider si une variable $Word est l'un des mots définis. J'ai besoin de quelque chose comme ça:

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

bash a-t-il une telle construction? Sinon, quel serait le plus proche?

61
Martin Vegter

Il s'agit d'une solution Bash uniquement (> = version 3) qui utilise des expressions régulières:

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

Si votre liste de mots est longue, vous pouvez la stocker dans un fichier (un mot par ligne) et procédez comme suit:

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

Une mise en garde avec l'approche par fichier:

  • Il se cassera si le fichier contient des espaces. Cela peut être résolu par quelque chose comme:

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

Merci à @terdon de m'avoir rappelé de bien ancrer le motif avec ^ et $.

64
Joseph R.
case $Word in
    dog|cat|horse) echo yes;;
    *)             echo no;;
esac
83
John Kugelman

Que diriez-vous:

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

Alors:

$ a.sh cat
cat is in the list
$ a.sh bob
bob is not in the list
11
terdon
if (echo "$set"  | fgrep -q "$Word")
3
BrenoZan

je cherchais une solution "une ligne" pour valider mon argument de script, et j'ai utilisé réponse Joseph R. ci-dessus pour trouver:

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

1
RASG

Vous pouvez utiliser fgrep pour spécifier tous les mots autorisés:

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

Le -w le drapeau ne correspond qu'aux mots entiers, le -q flag le fait fonctionner silencieusement (car tout ce dont nous avons besoin est la valeur de retour de l'instruction if à utiliser), et chaque -e pattern spécifie un modèle à autoriser.

fgrep est la version de grep qui fait une correspondance de chaîne normale au lieu d'une correspondance d'expression régulière. Si vous avez grep, vous devriez avoir fgrep, mais sinon, c'est identique à l'utilisation de grep avec le -F flag (il vous suffit donc de remplacer fgrep -wq ci-dessus avec grep -Fwq).

1
Christopher Shroba

Vous pouvez définir une fonction bash pour cela:

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

Ensuite, utilisez simplement comme ceci:

Word_valid cat
1
suspectus

Si les mots sont une liste où les valeurs sont séparées par une nouvelle ligne, vous pouvez faire:

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

Cela a fonctionné pour moi:

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

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

Vous voudrez peut-être mettre la liste des mots dans un fichier, au cas où vous changez souvent la liste, ou si vous souhaitez qu'elle soit partagée par plusieurs scripts. Et vous devrez peut-être mettre les mots dans un fichier si la liste devient trop longue à gérer dans un script. Ensuite, vous pouvez dire

if fgrep –qx "$Word" Word_list
0
Scott