var
与えられた変数(例えば)が与えられた文字列のリスト内の単語で始まるかどうかを確認する関数を書きたいです。このリストは変更されません。
インスタンス化するために、またはvar
で始まるかどうかを確認したいとしますaa
。abc
3@3
var
また、文字が含まれていることを確認したいと思います>
。
この関数が呼び出されると仮定すると、check_func
私の意図された用途は次のとおりです。
if check_func "$var"; then
do stuff
fi
aardvark
たとえば、とのために「何かを行う」必要がありますabcdef
。[email protected]
12>5
私は見たこの問題ユーザーが作品の一部を提供する状況:
beginswith() { case $2 in "$1"*) true;; *) false;; esac; }
上記のリストを繰り返し、この機能を使用するという考えです。私の難しさは、シャットダウン(または復帰に代わるもの)がこれをどのように行うべきかを正確に理解していないことです。
答え1
check_prefixes () {
value=$1
for prefix in aa abc 3@3; do
case $value in
"$prefix"*) return 0
esac
done
return 1
}
check_contains_gt () {
value=$1
case $value in
*">"*) return 0
esac
return 1
}
var='aa>'
if check_prefixes "$var" && check_contains_gt "$var"; then
printf '"%s" contains ">" and starts with one of the prefixes\n' "$var"
fi
テストを2つの機能に分けました。case ... esac
これが決定されると、両方が使用され、成功(0)を返します。一致するものがない場合は、 failure(1) が返されます。
プレフィックスリストを動的リストのようにするには、最初の関数を次のように書くことができます。
check_prefixes () {
value=$1
shift
for prefix do
case $value in
"$prefix"*) return 0
esac
done
return 1
}
(確認する値は最初のパラメータです。これを関数のパラメータリストに保存し、関数のパラメータリストから削除します。残りのパラメータを繰り返します。)次に、value
次shift
のように呼び出します。
check_prefixes "$var" aa abc 3@3
2番目の機能も同様の方法で変更できます。
check_contains () {
value=$1
shift
case $value in
*"$1"*) return 0
esac
return 1
}
(任意の部分文字列を確認してください)または
check_contains_oneof () {
value=$1
shift
for substring do
case $value in
*"$substring"*) return 0
esac
done
return 1
}
(複数のサブストリングのいずれかを確認してください)
答え2
バッシュの場合:
正規表現のプロパティを使用すると、何もstart
含めたり含めたりせずに^
作成できますcontain
。
確認する正規表現のリストスタートそしてaa
abc
または3@3
そして含む >
例:
^aa ^abc ^3@3 >
それを作る適切にリストを引用してbashに正規表現(=~
)を使用するように依頼してください。
check_func() {
matched=1
for test_regex in '^aa' '^abc' '^3@3' '>'; do
if [[ $var =~ $test_regex ]] ; then
matched=0
break
fi
done
return "$matched"
}
var='aaIsAMatch'
if check_func; then
echo "A match was found"
fi
関数にはマッチリストと変数名がハードコーディングされています。
配列変数の正規表現のリストと、最初の引数をテストする値が提供されます。
check_func() {
local matched; matched=1
for t in "${test_regex[@]}"; do
[[ $1 =~ $t ]] && { matched=0; break; }
done
return "$matched"
}
test_regex=('^aa' '^abc' '^3@3' '>')
if check_func 'aaIsAMatch'; then
echo "A match was found"
fi
この関数は、変数名(値の代わりに)を最初の引数として使用するようにさらに拡張できます。
POSIX
posixシェルには正規表現がなく、テストできる唯一の方法はCaseステートメントであるため、Caseステートメントを使用する必要があります。残念ながら、以前のシェル([拡張globは利用できません] [1])では、すべてのテストを繰り返す必要があります。そしてglobは次のようになります。
'aa*' 'abc*' '3@3*' '*>*'
複数のglobに対して複数の入力文字列をテストするスクリプト例:
check_func() { :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; #break;; esac
echo "matched $value with $t"
;;
esac
done
return "$matched"
}
for var in abdg wabcde aadef abcde 3@3hello hmm3@3hell 'we>we' 'a>dfff' 'dfd>' 'a> de' 'a*> fg'; do
if check_func "$var" 'aa*' 'abc*' '3@3*' '*>*'; then
echo "========A match was found for \"$var\""
fi
done
この関数の単純なバージョンは、正確に必要なタスクを実行します。
check_func() { :
matched=1
value=$1; shift
for t in "$@"; do
case $value in $t) matched=0; break;; esac
done
return "$matched"
}
答え3
このステートメントの役割は、case
2番目のパラメータを関数($2
)に渡すことです。パターンと一致する場合"$1"*
、つまり関数の最初のパラメータの後に何もない場合、true
ステートメントは実行され終了しますcase
。true
何も実行せずに状態0を返します。それ以外の場合、一致するもの、*
つまり何もない場合は、false
ステートメントが実行され終了しますcase
。false
何もしないで状態 1 を返します。したがって、case
2番目のパラメーターが最初のパラメーターで始まる場合、ステートメントの状況は0、そうでない場合は1です。これは関数の最後の(そして唯一の)ステートメントなので、関数は2番目の引数が最初の引数で始まる場合は0を返し、そうでない場合は1を返します。
条件文(if
シェルの条件文など)が0を返す場合、その文はtrueと見なされ、そうでない場合はfalseと見なされます。したがって、値が次から始まる場合は、それ以外の場合は印刷してくださいif beginswith "$var" "string"; then echo yes; else echo no; fi
。yes
var
string
no
この関数を書く方法はいくつかあります。たとえば、作成者は関数の最後のステートメントなので、andの代わりにreturn 0
orを使用できます。関数は、関数パラメータ(および)への参照を使用したい文字列に変更して、関数にラップすることなく関数本体を直接使用できるように作成されました。return 1
true
false
$1
$2
複数のプレフィックスを許可するには、ループで繰り返します。一致するプレフィックスが見つかると、true(0)状態の関数から返されます。一致するプレフィックスがない場合は、エラー状態(通常は1)が返されます。
# begins_with STRING PREFIX1 PREFIX2...
# Test if STRING starts with any of PREFIX1, PREFIX2, ...
begins_with () {
string=$1
shift
for prefix in "$@"; do
case "$string" in
"$prefix"*) return 0;;
esac
done
return 1
}
if begins_with "$var" 'aa' 'abc' '3@3'; then
echo "The value starts with one of the permitted prefixes"
fi
サフィックスをテストするには、代わり*"$suffix"
にパターンを"$prefix"*
使用します。部分文字列をテストするには、*"$substring"*
ここで二重引用符を使用する必要があります。それ以外の場合、変数はパターンとして解釈されます。たとえば、
suffix='?'
case "$var" in
*"$suffix") echo "The value of var ends with a question mark";;
esac
case "$var" in
*$suffix) echo "The value of var is not empty";;
esac
答え4
質問の説明に従って修正されました。 これはあまりエレガントであまり柔軟ではありませんが、他の答えよりもコンパクトです。
check_func() {
case "$1" in
( aa* | abc* | 3@3* | *">"*)
return 0
esac
return 1
}
aardvark
これは、およびabcdef
に対してtrueを返します。もちろん、、があります。[email protected]
12>5
aard>vark
abc<def>ghi
3@3>3