
文字列を含む変数があり、他の部分文字列に基づいてその場所に基づいて部分文字列を抽出したいと思います。私の解決策は、文字列が関数にパラメータとして送信されない限り動作するようです。私はbashシェルを使用しています。
#!/usr/bin/bash
var0="-a check one two three"
var1="check"
function getsubstr() {
echo ${*#*"${2}"}
}
# this prints 'one two three' which is what I want
echo ${var0#*"${var1}"}
# this prints '-a one two three', not what I want.
getsubstr $var0
echo $*
関数を入れるとgetsubstr
(->'-a check one two three') のような文字列が印刷され、関数を入れると (->'check') のような文字列が印刷されます。したがって、どちらの場合も、同じ部分文字列を印刷するように要求するようです。$var0
echo $2
getsubstr
$var1
もう一つの困難は、私が使用している関数echo ${*#*"${2}"}
にない場合でも同じ結果を得ることです。getsubstr
echo ${*%"${2}"*}
この動作を理解していただきありがとうございます。
${*:3}
ところで、関数内でgetsubstr
私が望む部分文字列を返すことは可能であることを知っていますが、理解して#*<regexp>
行動%<regextp>*
しようとしています。
答え1
getsubstr $var0
5つのパラメータを関数に渡しています。
また、$ *と$ @は両方をテストします。$1$2$ など...引数オブジェクト#柄。
正規表現についてbash
:最後にいくつかの例を追加しました。ところで、「*」はただ特殊正規表現文字正規表現のコンテキストで使用される場合、つまり。使用するとき =~。 * in が初めて使用されるときに${*
アスタリスクを特別に使用する方法は次のとおりです。(医師)名var はすべての変数の連結に拡張されます: $1 $2 $... etc...
アスタリスクの 2 番目の使用は次のことを#*"${2}"
意味します。"$2"の前には何もありません、渡された各 $1 などの引数と個別に/個別に一致します。
次のスクリプトは $@ や $* (例:) に役立ちます。
#!/bin/bash
#
getsubstr() {
echo -n " ${#@} args";
[[ "$1$2$3$4$5$6" == *\ * ]] && echo " (with embedded spaces)" || echo " (no spaces)"
echo ' "${*}" '\|"${*}"\|
echo ' ${*} '\|${*}\|
echo ' "${@}" '\|"${@}"\|
echo ' ${@} '\|${@}\|
echo ' "${*#*"${2}}" '\|"${*#*"${2}"}"\|
echo ' ${*#*"${2}} '\|${*#*"${2}"}\|
echo ' "${@#*"${2}}" '\|"${@#*"${2}"}"\|
echo ' ${@#*"${2}} '\|${@#*"${2}"}\|
echo ' ${*#B} '\|${*#B}\|
echo ' "${*#B}" '\|"${*#B}"\|
echo ' ${@#B} '\|${@#B}\|
echo ' "${@#B}" '\|"${@#B}"\|
}
var0="a B c "
echo
echo -n "Passing "; getsubstr "$var0" ; echo
echo -n "Passing "; getsubstr $var0 ; echo
echo -n "Passing "; getsubstr "$var0" "$var0" ; echo
echo -n "Passing "; getsubstr $var0 $var0 ; echo
echo
exit
###################################################################
正規表現bash
# Regex checks: "=~" uses extended regular expression
#+ Parenthesized subexpressions within the regular expression are saved
#+ in the array variable BASH_REMATCH
#+ $BASH_REMATCH / ${BASH_REMATCH[0]} is the string matching the entire regular expression.
#+ ${BASH_REMATCH[n]} is the sub string matching the nth parenthesized subexpression
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# $BASH_REMATCH"
# abc
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[0]}"
# abc
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[2]}"
# b
[[ "abcdef" =~ (.)(.)(.) ]] && echo "# ${BASH_REMATCH[@]}"
# abc a b c
答え2
説明で更新
このタイプの動作が表示されるのは、すべての位置パラメータに拡張される$*
ためです。実行しようとすると$@
$1
$2
パラメータ拡張(PE)これら2つの特殊変数のうちの1つの各位置引数にPEを適用します。いいえ単一の文字列。
から抜粋man bash
${パラメータ#単語}
一致するプレフィックスパターンを削除します。パス名拡張と同様に、単語を拡張してパターンを生成します。パターンがパラメータ値の先頭に一致する場合、拡張結果は#'' case) or the longest matching pattern (the
最も短い一致パターンが削除されたパラメータの拡張値です(## ''ケース)。 引数が@または*の場合、パターン除去操作は各位置引数に順番に適用され、拡張は結果リストになります。
本質的にあなたがしていることは次のとおりです。
getsubstr() {
tmp=$2
for arg; do
printf "%s " ${1#*$tmp}
shift
done
}
次の関数はPEを通常の変数に一度適用するので、一時変数を設定して$*
機能します。$tmp
getsubstr() {
tmp=$*
echo ${tmp#*$2}
}
ポリスチレン
function
POSIXではないので使用しないでください。()
すでに関数名の後に使用している場合は、まったく必要ありません。
ポリフェニレンスルフィド
これは実際には次のとおりです。一般的な表現代わりに球形表現。より正式にはこれを次のように呼びます。パラメータ拡張