bash: tes apakah $ WORD di set

54

Saya mencari konstruk bash, untuk memutuskan apakah variabel $WORDadalah salah satu kata yang didefinisikan. Saya butuh sesuatu seperti ini:

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

apakah bash memiliki konstruksi seperti itu? Jika tidak, apa yang paling dekat?

Martin Vegter
sumber

Jawaban:

57

Ini adalah solusi Bash-only (> = versi 3) yang menggunakan ekspresi reguler:

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

Jika daftar kata Anda panjang, Anda dapat menyimpannya dalam file (satu kata per baris) dan lakukan ini:

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

Satu peringatan dengan pendekatan file:

  • Ini akan rusak jika file memiliki spasi. Ini dapat diatasi dengan sesuatu seperti:

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

Terima kasih kepada @terdon karena mengingatkan saya untuk menempelkan pola dengan ^dan $.

Joseph R.
sumber
1
Dan shopt -s nocasematchmungkin membantu jika Anda ingin pencarian menjadi case-sensitive.
Skippy le Grand Gourou
1
Perhatikan bahwa Anda harus menggunakan [[dan ]]- [dan ]tidak cukup.
Greg Dubicki
saya sedang mencari 'oneliner' untuk memvalidasi argumen skrip saya, dan ini bekerja dengan sempurna. Terima kasih! [[ "$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 mendukung Monica
sumber
11

Bagaimana tentang:

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

Kemudian:

$ a.sh cat
cat is in the list
$ a.sh bob
bob is not in the list
terdon
sumber
3
if (echo "$set"  | fgrep -q "$WORD")
BrenoZan
sumber
1
Meskipun hati-hati, ini akan mengembalikan true jika $WORDkosong, maka akan cocok jika WORD=caatau WORD=ogatau serupa dan saya menganggap Anda berarti echo ${set[@]}.
terdon
cukup tambahkan -w ke grep untuk menghindari sebagian kata
BrenoZan
1

Anda bisa mendefinisikan fungsi bash untuk ini:

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

Kemudian gunakan seperti ini:

word_valid cat
tersangka
sumber
1

saya sedang mencari solusi 'satu baris' untuk memvalidasi argumen skrip saya, dan menggunakan Joseph R. jawaban di atas untuk menghasilkan:

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

RASG
sumber
0

Ini bekerja untuk saya:

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

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

Anda mungkin ingin memasukkan daftar kata ke dalam file, jika Anda sering mengubah daftar, atau Anda ingin itu dibagikan oleh banyak skrip. Dan Anda mungkin perlu memasukkan kata-kata ke dalam file jika daftar terlalu panjang untuk dikelola dalam skrip. Maka Anda bisa mengatakannya

if fgrep qx "$WORD" word_list
Scott
sumber
tidak, saya tidak ingin memiliki daftar saya di file
Martin Vegter
0

Jika kata-kata adalah daftar di mana nilai dipisahkan oleh baris baru, Anda dapat melakukan:

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

Anda dapat menggunakan fgrep untuk menentukan semua kata yang diizinkan:

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

The -wbendera cocok hanya kata-kata penuh, -qbendera membuatnya beroperasi diam-diam (karena semua yang kita butuhkan adalah nilai kembali untuk jika pernyataan untuk digunakan), dan masing-masing -epola Menentukan pola untuk memungkinkan.

fgrepadalah versi grep yang melakukan pencocokan string normal dan bukan pencocokan regex. Jika sudah grep, Anda harus melakukannya fgrep, tetapi jika tidak, itu identik dengan menggunakan grepdengan -Fflag (jadi Anda hanya perlu mengganti fgrep -wqdengan di atas grep -Fwq).

Christopher Shroba
sumber