读取多行分隔的子字符串到bash数组

时间:2017-12-04 09:46:05

标签: 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我只从每个字符串中获得第一个子字符串(在分号之前)。我做错了什么?

3 个答案:

答案 0 :(得分:2)

使用read -ra,您基本上是在读取数组SUBSTR,但只是尝试在字符串变量的上下文中打印它。尝试打印整个数组,该数组应该存储完整的行。

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

还要注意-a代码中前面的LINE用法,其中整行存储为数组。

此外,如果您安装了最新版本的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-loop

一次打印一个元素
for entry in "${wholeArray[@]}"; do
    printf '%s\n' "$entry"
done

也总是使用大写变量来存储变量名,以免与shell维护的环境变量混淆。

答案 1 :(得分:0)

另一种分割字符串的方法,使用shell扩展并避免读取缓慢:

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

答案 2 :(得分: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"