次のIFS
コマンドは予想される出力を提供しません。
$ IFS='=' read -r key value <<< "fram-saml-idp-signing-certificate=MIIDYTCCAkmifzlwq5yziqyU04eP4wLr3cM="; echo "KEY: ${key}";echo "VALUE: ${value}"
出力:
KEY: fram-saml-idp-signing-certificate
VALUE: MIIDYTCCAkmifzlwq5yziqyU04eP4wLr3cM
最後の等号(=)がありません。
ただし、次のコマンドは正しい推定出力を提供します。
$ IFS='=' read -r key value <<< "fram-saml-idp-signing-certificate=MIIDYTCCAkmifzlwq5yziqyU04eP4wLr3cM=="; echo "KEY: ${key}";echo "VALUE: ${value}"
出力:
KEY: fram-saml-idp-signing-certificate
VALUE: MIIDYTCCAkmifzlwq5yziqyU04eP4wLr3cM==
これはバグですかIFS
?=
最後に等号()があるときに正しい出力を得るには、最初のコマンドをどのように変更する必要がありますか?
答え1
強力で移植可能なソリューションは、変数とその変数(パラメータ?)拡張を使用することです。
str="fram-saml-idp-signing-certificate=MIIDYTCCAkmifzlwq5yziqyU04eP4wLr3cM="
key=${str%%=*} # select the string up to the first =
value=${str#"$key="} # take all that is not the variable above.
echo "KEY: ${key}";echo "VALUE: ${value}"
すべてのBourneシェル(ksh、bash、zsh、古いBourneシェル自体を除く)で動作します。
詳細
「単語の分割」の規則は非常に複雑です(詳細については、以下の関連リンクを読んでください。「特別なケース」がたくさんあります)。
2 つ以上の末尾の区切り記号は次のとおりです。いいえすべてのシェルを削除します。ただし、dash、bash、ksh では末尾の区切り文字が削除されます (ただし、zsh は削除しません)。
選ぶ
強力なソリューションバッシュから正規表現の一致を使用していますか?
str='fram-saml-idp-signing-certificate=MIIDYTCCAkmifzlwq5yziqyU04eP4wLr3cM='
re='^([^=]*)=(.*)';
[[ $str =~ $re ]] && key="${BASH_REMATCH[1]}" value="${BASH_REMATCH[2]}";
echo "KEY: ${key}";echo "VALUE: ${value}"
これにより、以下が(正しく)印刷されます。
KEY: fram-saml-idp-signing-certificate
VALUE: MIIDYTCCAkmifzlwq5yziqyU04eP4wLr3cM=
関連
答え2
単一の区切り文字で終わる最後のフィールドの場合、既知のすべてのシェルが同意し、区切り文字を削除します。
末尾の区切り文字が複数ある場合、状況によって異なり、特定の動作を期待できるかどうか疑問です。
Bourne Shell
、およびのPOSIXバリアントには、後に空でないフィールドがある場合にのみ、ksh88
最後の変数に区切り文字が含まれます。ksh88
bosh
ksh93
bash
末尾の区切り文字が複数ある場合は、入力の未変更の残りの部分が含まれます。
POSIX ステートメント:
If there are fewer vars than fields, the last var shall
be set to a value comprising the following elements:
ただし、2つの区切り文字の間の空のフィールドが1つのフィールドと見なされるかどうかは説明できません。したがって、私の理解によると、ksh88
動作ksh93
は正確である可能性があるため、正確な動作が定義されていないようです。