【问题标题】:Bash issue with concatenation within while read loop在读取循环中连接的 Bash 问题
【发布时间】:2018-02-15 14:03:41
【问题描述】:

通过以下代码,我尝试从预生成的输入文件构造一个开始/结束对的输出数组,以便在脚本的其他地方使用。但是我遇到了一个问题,不是将结束数据连接到开始数据上,而是覆盖了已经存在的数据?

#!/bin/bash

echo "Init arrays"
far=()
near=()
echo "Start while"
while read -u2 line; do
    echo "    $line"
    if [[ "$line" == "Far Start"* ]]; then
        far+=(${line##* })
        echo ${far[-1]}
    elif [[ "$line" == "Far End"* ]]; then
        far[-1]+="-${line##* }"
        echo ${far[-1]}
    elif [[ "$line" == "Near Start"* ]]; then
        near+=(${line##* })
        echo ${near[-1]}
    elif [[ "$line" == "Near End"* ]]; then
        near[-1]+="-${line##* }"
        echo ${near[-1]}
    fi
done 2<screenlog.0

echo
echo "  Far array"
for each in "${far[@]}"
do
  echo "$each"
done
echo "  Near array"
for each in "${near[@]}"
do
  echo "$each"
done

输入文件(screenlog.0):

User Input: 955
Stepping Pass 1/6
Far Start 213994
Far End 216994
Near Start 221795
Near End 224795
Stepping Pass 2/6
Far Start 229596
Far End 232596
Near Start 237397
Near End 240397
Stepping Pass 3/6
Far Start 245198
Far End 248198
Near Start 252999
Near End 255999
Stepping Pass 4/6
Far Start 260800
Far End 263800
Near Start 268601
Near End 271601
Stepping Pass 5/6
Far Start 276402
Far End 279402
Near Start 284203
Near End 287203
Stepping Pass 6/6
Far Start 292004
Far End 295004
Near Start 299805
Near End 302805
Finished!

错误输出:

Init arrays
Start while
    User Input: 955
    Stepping Pass 1/6
    Far Start 213994
213994
    Far End 216994
-216994
    Near Start 221795
221795
    Near End 224795
-224795
    Stepping Pass 2/6
    Far Start 229596
229596
    Far End 232596
-232596
    Near Start 237397
237397
    Near End 240397
-240397
    Stepping Pass 3/6
    Far Start 245198
245198
    Far End 248198
-248198
    Near Start 252999
252999
    Near End 255999
-255999
    Stepping Pass 4/6
    Far Start 260800
260800
    Far End 263800
-263800
    Near Start 268601
268601
    Near End 271601
-271601
    Stepping Pass 5/6
    Far Start 276402
276402
    Far End 279402
-279402
    Near Start 284203
284203
    Near End 287203
-287203
    Stepping Pass 6/6
    Far Start 292004
292004
    Far End 295004
-295004
    Near Start 299805
299805
    Near End 302805
-302805
    Finished!

  Far array
-216994
-232596
-248198
-263800
-279402
-295004
  Near array
-224795
-240397
-255999
-271601
-287203
-302805

关于预期结果,far 数组最终应如下所示(即开始编号后跟分隔符,后跟结束编号)。 near 数组应该是相同的,只是从 near 数据中提取。

[0] 213994-216994
[1] 229596-232596
[2] 245198-248198
[3] 260800-263800
[4] 276402-279402
[5] 292004-295004

我尝试了array[-1]="${array[-1]}-${line##* }" 语法,结果相同,并更改了分隔符并使用${array[@]:-1} 引用数组的最后一个元素。

编辑:按照 William 的建议,我尝试用 far[$((${#far[@]}-1))] 替换所有 far[-1] 语法实例,这导致与 far[-1] 语法相同的错误输出。

【问题讨论】:

  • 请提供一个具体示例,说明从样本输入中获得的所需输出。
  • 尽量避免使用 [-1] 语法并使用更丑的:far[$((${#far[@]}-1))]+="..."
  • 坦率地说,看起来数组并不是您真正想要的。只需创建一个逗号(或空格)分隔的字符串,例如“213994-216994,229596-232596”。

标签: bash file-io while-loop string-concatenation


【解决方案1】:

代替for each .. echo ..,使用declare -p far near查看是否有不可打印字符

可以打印类似

的东西
declare -a far=([0]=$'213994\r-216994\r' [1]=$'229596\r-232596\r' [2]=$'245198\r-248198\r' [3]=$'260800\r-263800\r' [4]=$'276402\r-279402\r' [5]=$'292004\r-295004\r')
declare -a near=([0]=$'221795\r-224795\r' [1]=$'237397\r-240397\r' [2]=$'252999\r-255999\r' [3]=$'268601\r-271601\r' [4]=$'284203\r-287203\r' [5]=$'299805\r-302805\r')

如果是这种情况,'\r' 字符可以删除,添加

line=${line%$'\r'}

刚读完(更确切地说是在do之后,否则while循环永远不会结束)

【讨论】:

  • 它为远阵列打印出")'5004292004r='([0]="213994,为近阵列打印")'2805299805ar='([0]="221795。添加该附加行已解决了该问题。
猜你喜欢
  • 2019-03-23
  • 2022-01-22
  • 2018-04-13
  • 1970-01-01
  • 2018-08-01
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多