1

名前と値のペアで構成されるファイルを処理するための KSH スクリプトを作成しようとしています。

形式は次のとおりです。

NAME1 VALUE1,NAME2 VALUE2,NAME3 VALUE3, etc

私が書くとしましょう:

read l
IFS=","
set -A nvls $l
echo "$nvls[2]"

これにより、2 番目の名前と値のペアが簡単に得られます。ここで、値にカンマを含めることができるようにタスクが拡張されたとします。次のようにエスケープする必要があります。

NAME1 VALUE1,NAME2 VALUE2_1\,VALUE2_2,NAME3 VALUE3, etc

「読み取り」はすべての引用符を取り除き、配列の2番目の要素は「NAME2 VALUE2_1」になるため、明らかに、私のコードは機能しなくなりました。

「読み取り -A 配列」を持たない古い ksh で立ち往生しています。「read -r」と「eval set -A ....」でさまざまなトリックを試しましたが、役に立ちませんでした。「read nvl1 nvl2 nvl3」を使用して読み取り内でアンエスケープと分割を行うことはできません。これは、各行に名前と値のペアがいくつあるかを事前に知らないためです。

誰かが私のために役立つトリックを持っていますか?

PS Perl、Python、さらには awk でこれを行ったことがあることを知っています。ただし、kshで実行する必要があります(...または試してみてください;)

4

2 に答える 2

1

よくあることですが、公開フォーラムで質問してから数分後に回答を用意しました :(

次のsedスクリプトを介して入力ファイルをパイプすることにより、引用/引用解除の問題を回避しました。

sed -e 's/\([^\]\),/\1\
/g;s/$/\
/

入力を次のように変換しました。

NAME1.1 VALUE1.1
NAME1.2 VALUE1.2_1\,VALUE1.2_2
NAME1.3 VALUE1.3
<empty line>
NAME2.1 VALUE2.1
<second record continues>

これで、この入力を次のように解析できます。

while read name value ; do
  echo "$name => $value"
done

値のコンマは「読み取り」によって引用符で囲まれていないため、必要に応じて連想配列に「名前」と「値」を入れることができます。

PS私は自分の答えを受け入れることができないので、質問を削除する必要がありますか、それとも...?

于 2008-10-05T13:06:03.093 に答える
0

また、\,パターンをどの文字列にも表示されないことがわかっている別のパターンに変更し、入力を配列に分割した後でパターンを元に戻すこともできます。これを行うには、ksh組み込みのパターン置換構文を使用できます。sedやawkなどを使用する必要はありません。

read l
l=${l//\\,/!!}
IFS=","
set -A nvls $l
unset IFS
echo ${nvls[2]/!!/,}
于 2008-10-30T02:54:06.837 に答える