bash
で構成を探しています。変数$WORD
は定義された単語の1つです。次のようなものが必要です:
if "$WORD" in dog cat horse ; then echo yes else echo no fi
bashにはそのような構成がありますか?そうでない場合、最も近いものは何ですか?
回答
これはBashのみ(> =バージョン3)のソリューションです。正規表現を使用します:
if [[ "$WORD" =~ ^(cat|dog|horse)$ ]]; then echo "$WORD is in the list" else echo "$WORD is not in the list" fi
単語リストが長い場合は、ファイルに保存して(1行に1単語)、次のようにします。
if [[ "$WORD" =~ $(echo ^\($(paste -sd"|" /your/file)\)$) ]]; then echo "$WORD is in the list" else echo "$WORD is not in the list" fi
ファイルアプローチに関する1つの注意点:
-
ファイルに空白があると壊れます。これは、次のような方法で修正できます。
sed "s/[[:blank:]]//g" /your/file | paste -sd "|" /dev/stdin
および$
。
コメント
回答
case $word in dog|cat|horse) echo yes;; *) echo no;; esac
回答
どうですか:
#!/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"
次に:
$ a.sh cat cat is in the list $ a.sh bob bob is not in the list
回答
if (echo "$set" | fgrep -q "$WORD")
コメント
- ただし、
$WORD
が空の場合はtrueが返され、WORD=ca
またはWORD=og
などで、echo ${set[@]}
を意味していると思います。 - 追加するだけです-単語の一部を避けるためにgrepを実行する
回答
このためのbash関数を定義できます:
function word_valid() { if [ "$1" != "cat" -a "$1" != "dog" -a "$1" != "horse" ];then echo no else echo yes fi }
次に、次のように簡単に使用します。
word_valid cat
回答
スクリプト引数を検証するための「1行」のソリューションを探していたところ、上記の Joseph R. answer を使用しました。 up with:
[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
回答
あなたfgrepを使用して、許可されるすべての単語を指定できます。
if $(echo "$WORD" | fgrep -wq -e dog -e cat -e horse) ; then echo yes else echo no fi
-w
フラグは、完全な単語にのみ一致します。-q
フラグはサイレントに動作し(必要なのは使用するifステートメントの戻り値だけであるため)、各-e
パターンはパターンを指定します許可します。
fgrep
は、正規表現マッチングの代わりに通常の文字列マッチングを行うgrepのバージョンです。 grep
がある場合は、fgrep
が必要ですが、そうでない場合は、grep
に-F
フラグを付けます(したがって、上記のfgrep -wq
をgrep -Fwq
)。
回答
これでうまくいきました:
#!/bin/bash phrase=(cat dog parrot cow horse) findthis=parrot for item in ${phrase[*]} do test "$item" == "$findthis" && { echo "$findthis found!"; break; } done
回答
リストを頻繁に変更する場合に備えて、単語のリストをファイルに入れたい場合があります。複数のスクリプトで共有されます。リストが長すぎてスクリプトで管理できない場合は、単語をファイルに入れる必要があります。
if fgrep –qx "$WORD" word_list
コメント
- いいえ、'リストをファイルに入れたくない
回答
単語が値を改行で区切ったリストである場合は、次の操作を実行できます。
WORDS="$(ls -1)" if echo "${WORDS}" | grep --quiet --line-regexp --fixed-strings "${WORD}"; then echo yes else echo no fi
回答
同じ問題が発生し、正規表現の知識を必要としない驚くほど理解しやすい解決策を見つけました。
注意してください。以下に示すソリューションは、bashと他のシェルの違いについての手がかりがないため、bashのみである可能性があります。さらに、bashのマニュアルでは、照合する必要のある文字列が長い場合、この種のパターン照合は遅くなると警告しています。
WORD=abc [[ "$WORD" == @(def|abc|ghi|foo|barbaz) ]] && echo Word is in set.
これはどのように機能しますか?ここでbashマニュアルの大部分を繰り返したくはありませんが、私自身の言葉で:
二項演算子==
が複合コマンドで使用されている場合[[
、セクション"パターンマッチング bashマニュアル。さらに、これらの条件下では、一致している間、シェルオプションextglob
が設定されていると想定されます(実際の設定に関係なく)。上記を理解する上での重要なポイント。
しかし、セット内の単語に、パターンマッチング、コマンド置換、その他の展開で特別な意味を持つ文字がすでに含まれている場合はどうでしょうか。解決策は簡単です。次のようなものを使用するだけです。
[[ "$WORD" == @("a*"|abc|"?ghi"|"$DontExpandMe"|barbaz) ]] && echo Word is in set.
これは非常に簡単で、理解しやすく、効率的であることがわかりました($WORD
が短い限り)副作用がない、またはdaであるソリューションset
ベースのメソッドのように素晴らしいです。
shopt -s nocasematch
は、検索で大文字と小文字を区別しないようにする場合に役立つことがあります。[[
と–
[
と]
では不十分です。[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
egrep -q "^$WORD$" /tmp/words; [[ $? != 0 ]] && echo "Not found" || echo "OK"
。