2017-12-04 3 views
2

に複数行区切りのサブ文字列を読む私は、次のコードからbashのアレイ

Speed: 10500 Mbps 
Size: 122400 MB 
Load: 4544 Kg 
Distance: 232680 miles 
Acceleration: 11200 meters/s2 
Deviation: 1100 Wierdos 

を含む配列を作成したい:

read -r -d '' TEST_STRING << EOM 
Speed: 10500 Mbps; Size: 122400 MB 
Load: 4544 Kg; Distance: 232680 miles 
Acceleration: 11200 meters/s2; Deviation: 1100 Wierdos 
EOM 

STRINGS_ARRAY=() 
RE_INTRALINEDELIMITER=";" 

while IFS=$'\n' read -a LINE; do 

    if [[ $LINE =~ $RE_INTRALINEDELIMITER ]]; then  
     echo "(intraline): $LINE" 
     while IFS=$';' read -a SUBSTR; do 
      echo "(substr): $SUBSTR" 
     done <<< "$LINE" 

    fi 

done <<< "$TEST_STRING" 

(エコーがデバッグ用として追加されます空の演算子)。その後、いくつかの関数で行を処理し、最後に元の文字列に戻します。

しかし、SUBSTRについては、(セミコロンの前に)すべての文字列から最初のサブ文字列を取得します。私は間違っているの?

+0

私の答えはあなたのために働いたのですか?私はあなたの問題を解決すべき編集を作った – Inian

+0

私はあなたの下の答えをチェックしました(Nahuel Fouilleul)。私はあなたの答えをチェックしている間、あなたは見て、それが良いかどうか見ることができますか? – maaboo

+0

申し訳ありません。私は、私の答えではないというフィードバックを提供することはできません。しかし、私はあなたの試みとしてより効率的なアプローチをお勧めし、私の答えは試みた – Inian

答えて

2

read -raとすると、基本的には配列SUBSTRに読み込まれていますが、文字列変数のコンテキストでのみ印刷しようとしています。配列全体を印刷してみてください。配列全体が保存されているはずです。

echo "(substr): ${SUBSTR[@]}" 

また、あなたは配列として保存され、全体のラインを持っているLINEために、以前のコードで-a使用状況を気に。

さらに最近のバージョンのbashがインストールされている場合は、mapfile/readarrayを使用して、複数行の出力を配列に解析してみてください。あなたの全体の要件が非常によく、これはラインが;文字存在を持っているかどうかを確認するために一度に一つのエントリ各地からあなたのループ配列に文字列全体を格納

re_delimiter=';' 
mapfile -t stringArray <<<"$TEST_STRING" 

に減少させることができました。入力文字列内のすべての行から区切られたすべての文字列をすべて;に保存するためにここでwholeArrayを初期化しました。

wholeArray=() 
for line in "${stringArray[@]}"; do 
    substringArray=() 
    if [[ $line =~ $re_delimiter ]]; then 
     IFS=';' read -ra substringArray <<<"$line" 
     wholeArray+=("${substringArray[@]}") 
    fi 
done 

declare -p wholeArray 
declare -a wholeArray='([0]="Speed: 10500 Mbps" [1]=" Size: 122400 MB" [2]="Load: 4544 Kg" [3]=" Distance: 232680 miles" [4]="Acceleration: 11200 meters/s2" [5]=" Deviation: 1100 Wierdos")' 

(又は)も常に

for entry in "${wholeArray[@]}"; do 
    printf '%s\n' "$entry" 
done 

forループの適切なを使用して一度に要素1つを出力するようにアレイ全体のコンテンツを印刷シェルが保持する環境変数と混同しないように、変数名を格納するために大文字の変数を使用します。

0

シェル拡張を使用して、リードを避け、文字列を分割する別の方法としてどの遅いです:

tmp=$TEST_STRING 

while [[ $tmp = *[\;$'\n']* ]]; do 
    item=${tmp%%[;$'\n']*} # to remove the largest suffix starting with ; or newline 
    tmp=${tmp#*[;$'\n']}  # to remove the shortest prefix ending with ; or new line 
    echo "[$item]" 
done 
0

使用read二回。一度行を取得し、再度その行を分割します。

test_string='Speed: 10500 Mbps; Size: 122400 MB 
Load: 4544 Kg; Distance: 232680 miles 
Acceleration: 11200 meters/s2; Deviation: 1100 Wierdos' 

while IFS= read -r line; do 
    IFS=";" read -r fields <<< "$line" 
    strings_array+=("${fields[@]}") 
done <<< "$test_string"