プロパティファイルを連想配列として読み取るには?

プロパティファイルを連想配列として読み取るには?

属性を読みたいです。プロパティファイル連想配列として。どうすればいいですか?

解析対象の詳細:ハッシュと等号。他のすべてはボーナスです。

プロパティファイルの内容の例:

# comment
a=value-a
b=http://prefix.suffix:8080/?key=value
c=password_with\\backslash-and=equals

このファイルでbash連想配列を設定したいと思います。

 declare -A props='(
  [a]="value-a"
  [b]="http://prefix.suffix:8080/?key=value"
  [c]="password_with\\backslash-and=equals" )'

declare -p(この連想配列noteの期待される出力には${props[c]}1つのバックスラッシュしか含まれていません。"\\"'\'

ベストアンサー1

perl'などの実際のパーサーを使用してください。Config::Properties基準寸法。でスクリプト全体を完了しますが、perl使用する必要がある場合は、bash次のことができます。

typeset -A props
while IFS= read -rd '' key && IFS= read -rd '' value; do
  props[$key]=$value
done < <(
  perl -MConfig::Properties -l0 -e '
   $p = Config::Properties->new();
   $p->load(STDIN);
   print for $p->properties' < file.properties
)

(にも適用されますzsh)。

完全なパーサーを実装するにはbash多くの作業が必要で、車輪を再開発する必要があります。組み込み関数には次のプロパティファイルと非常によく似た入力形式が必要なので、while read単純なループを使用して良いサブセットを得ることができます。read

typeset -A props
while IFS=$':= \t' read key value; do
  [[ $key = [#!]* ]] || [[ $key = "" ]] || props[$key]=$value
done < file.properties

(連想配列をサポートする2つの異なるBourne様シェルインksh93と一緒に使用することもできます)。zsh

これは以下を処理します。

  • prop = value
  • prop: value
  • prop value
  • コメントは行の先頭にあります(オプション!#先行スペースがあります)。
  • バックスラッシュエスケープ(区切り文字またはを含むキーの例のようにfoo\:\:bar=valuefoo=\ barpassword_with\\backslash-and=equals
  • バックスラッシュを使用した行の連続

ところで確認してみると仕様

  • \n、、...シーケンスを処理しません\r\uXXXX

  • LFは唯一認識される行区切り文字です(CRまたはCRLFではありません)。

  • $IFSFFは空白として認識されません(シェルとバージョンによっては必ずしも\fIFS空白文字1として認識されるわけではないため、ここに追加することはできません)。

  • のような入力の場合は、代わりにfoo: bar = 保存してくださいbar(しかしそれも動作します)。属性値に(エスケープされていない)区切り文字(オプションでSPC / TAB文字で囲まれているか、オプションでSPC / TAB文字で囲まれているか、1つ以上のSPC / TAB文字シーケンス)が含まれていて、最後にある場合にのみ問題が発生します。 。${props[foo]}bar = foo: bar:baz::=

  • \!またはで始まるコメント行として扱われます\#。名前またはで始まる属性にのみ!問題があります#

  • 存在する

      prop=1\
       2\
       3
    

私たちが得ることは、1 2 3連続123した行の先行スペースが無視されないことです。


²IFS スペース文字[:space:]、各POSIXはロケール(通常は含まれていますが\f必須ではありません)として分類された文字で、正確に$IFSksh88(POSIX仕様に基づいています)であり、ほとんどのシェルではまだSPC、TAB、およびNLに制限されています。これに関して私が見つけた唯一のPOSIX互換シェルはですyashksh93bash5.0ベース)他のスペース(CR、FF、VTなど)も含まれていますが、シングルバイトスペースに制限されています(たとえば、Solaris)(一部の領域にはシングルバイトの切り捨て防止スペースが含まれています)

おすすめ記事