テキストファイルを読み、定義された内容をキーと値のペアに分割したいと思います。コンテンツは、キーと値を含む複数の行です。キーにはスペースがないため、最初のスペースはキーと値を区別します。ただし、値には単一または複数、または先行および末尾のスペースを含めることができます。私のスクリプトはうまくいきますが、1つの欠陥があります。つまり、複数のスペースをすべて削除するということです。私の値がファイルに記載されているものとまったく同じであることを願っています。
コアスクリプト:
#!/bin/bash
input="./inp.txt"
while IFS= read -r line
do
parts=($line)
key=${parts[0]}
value=${parts[@]:1:${#parts[@]}}
echo .
echo "Key: [$key]"
echo "Value: [$value]"
echo .
done < "$input"
入力ファイル(inp.txt):
KEY1 VAL1
KEY2 VAL2 has space & multi spaces & leading & trailing spaces.
KEY3 VAL3
KEY4 VAL4
KEY5 VAL5
出力:
Key: [KEY1]
Value: [VAL1]
.
.
Key: [KEY2]
Value: [VAL2 has space & multi spaces & leading & trailing spaces.]
.
.
Key: [KEY3]
Value: [VAL3]
.
.
Key: [KEY4]
Value: [VAL4]
.
.
Key: [KEY5]
Value: [VAL5]
予想:(KEY2-VALUE2確認)
Key: [KEY1]
Value: [VAL1]
.
.
Key: [KEY2]
Value: [ VAL2 has space & multi spaces & leading & trailing spaces. ]
.
.
Key: [KEY3]
Value: [VAL3]
.
.
Key: [KEY4]
Value: [VAL4]
.
.
Key: [KEY5]
Value: [VAL5]
答え1
標準のPOSIXパラメータ拡張を使用${parameter%%word}
して、最長の末尾の部分文字列を削除し、${parameter#word}
最短の先行部分文字列を削除できます。
#!/bin/bash
input="./inp.txt"
while IFS= read -r line
do
key=${line%% *}
value=${line#* }
echo .
echo "Key: [$key]"
echo "Value: [$value]"
echo .
done < "$input"
答え2
出力の各要素の代わりにsed
onを使用して、対応する数字と最初のスペースを$line
削除できます。KEY
$parts
#!/bin/bash
input="./inp.txt"
while IFS= read -r line
do
parts=($line)
key=${parts[0]}
value=$(echo "$line" | sed 's/KEY[[:digit:]]*[[:space:]]//')
echo .
echo "Key: [$key]"
echo "Value: [$value]"
echo .
done < "$input"