【问题标题】:Bash array only contains one element [duplicate]Bash数组仅包含一个元素[重复]
【发布时间】:2021-06-29 10:16:39
【问题描述】:

我是 bash 脚本的新手,正在努力学习。

我有一个变量 $temp,它包含我从 API 调用中获得的信息,它是一个长长的 SHA1 哈希列表。我想获取 $temp 中的内容并创建一个数组,我可以循环遍历并将每个条目与我定义的字符串进行比较。不知何故,我似乎无法让它工作。我创建的数组总是只包含一个元素。就像 $temp 中字符串的其余部分被忽略了。

我尝试了多种方法,但都无法按我想要的方式工作。 这是sn-p的代码:

temp=$(curl --silent --request GET "https://api.pwnedpasswords.com/range/$shortendHash")
echo "Temp is: $temp"

declare -A myArr
read myArr <<<$temp

echo ${myArr[@]}

echo ${myArr[0]}

echo ${myArr[1]}

当我运行这个时,我得到一个完整的哈希列表,当我回显 $temp(第 2 行)时,类似这样:

"温度为:002C3CADF9FC86069F09961B10E0EDEFC45:1 003BE35BD9466D19258E79C8665AFB072F6:1 0075B2ADF782F9677BDDF8CC5778900D986:8 00810352C02B145FF304FCBD5BEF4F7AA9F:1 013720F40B99D6BCF6F08BD7271523EBB49:1 01C894A55EBCB6048A745B37EC2D989F102:1 030B46D53696C8889910EE0F9EB42CEAE97:4 03126B56153F0564F4A6ED6E734604C67E8:2 043196099707FCB0C01F8C2111086A92A0B:1 0452CABBEF8438F358F0BD8089108D0910E:5 0490255B206A2C0377EBD080723BF72DDAE:2 05AD1141C41237E061460DB5CA5412C1A48:4 05C1D058E4439F8F005EFB32E7553E6AA5B:1 067AF515CC712AC4ACA012311979DBC7C9A:2 ...等等..”

但是

echo ${myArr[@]}

echo ${myArr[0]}

echo ${myArr[1]}

返回(第一个值为${myArr[@]},第二个为${myArr[0]},最后一个为空行,表示数组位置1没有值):

002C3CADF9FC86069F09961B10E0EDEFC45:1 002C3CADF9FC86069F09961B10E0EDEFC45:1

我希望有人可以帮助解决这个问题。

提前非常感谢!

【问题讨论】:

  • read 仅读取其输入的一行。
  • IFS=$'\n' read -r -d '' -a myArr &lt; &lt;(curl ... &amp;&amp; printf '\0') 将满足您的需求。根本没有理由拥有temp

标签: arrays bash shell scripting


【解决方案1】:
declare -A myArr # creates an associative array (hash)
declare -a myArr # creates an array

这里都不需要。 read 可以为您创建数组。请参阅help declarehelp read


temp=$(curl --silent --request GET "https://api.pwnedpasswords.com/range/$shortendHash")

# -a: assign the words read to sequential indices of the array
read -a myArr <<<"$temp"
declare -p myArr

输出:

声明-a myArr,该=([0] = “002C3CADF9FC86069F09961B10E0EDEFC45:1”[1] = “003BE35BD9466D19258E79C8665AFB072F6:1”[2] = “0075B2ADF782F9677BDDF8CC5778900D986:8”[3] = “00810352C02B145FF304FCBD5BEF4F7AA9F:1”[4] =” 013720F40B99D6BCF6F08BD7271523EBB49:1" [5] = “01C894A55EBCB6048A745B37EC2D989F102:1”[6] = “030B46D53696C8889910EE0F9EB42CEAE97:4”[7] = “03126B56153F0564F4A6ED6E734604C67E8:2”[8] = “043196099707FCB0C01F8C2111086A92A0B:1”[9] = “0452CABBEF8438F358F0BD8089108D0910E:5”[ 10] = “0490255B206A2C0377EBD080723BF72DDAE:2”[11] = “05AD1141C41237E061460DB5CA5412C1A48:4”[12] = “05C1D058E4439F8F005EFB32E7553E6AA5B:1”[13] = “067AF515CC712AC4ACA012311979DBC7C9A:2”)

【讨论】:

    【解决方案2】:

    假设 ...

    $(curl --silent --request GET "https://api.pwnedpasswords.com/range/$shortendHash")
    

    返回 ...

    002C3CADF9FC86069F09961B10E0EDEFC45:1
    003BE35BD9466D19258E79C8665AFB072F6:1
    0075B2ADF782F9677BDDF8CC5778900D986:8
    00810352C02B145FF304FCBD5BEF4F7AA9F:1
    013720F40B99D6BCF6F08BD7271523EBB49:1
    01C894A55EBCB6048A745B37EC2D989F102:1
    030B46D53696C8889910EE0F9EB42CEAE97:4
    03126B56153F0564F4A6ED6E734604C67E8:2
    043196099707FCB0C01F8C2111086A92A0B:1
    0452CABBEF8438F358F0BD8089108D0910E:5
    0490255B206A2C0377EBD080723BF72DDAE:2
    05AD1141C41237E061460DB5CA5412C1A48:4
    05C1D058E4439F8F005EFB32E7553E6AA5B:1
    067AF515CC712AC4ACA012311979DBC7C9A:2
    

    然后通过包装一组括号将其分配给数组:

    # unset current variable
    $ unset myArr
    
    # no need to issue a `declare`; the `myArr=( ... )` will automatically create `myArr` as a normal integer-indexed array
    $ myArr=( $(curl --silent --request GET "https://api.pwnedpasswords.com/range/$shortendHash") )
    
    # verify array contents:
    $ typeset myArr
    declare -a myarr=([0]="002C3CADF9FC86069F09961B10E0EDEFC45:1" [1]="003BE35BD9466D19258E79C8665AFB072F6:1" [2]="0075B2ADF782F9677BDDF8CC5778900D986:8" [3]="00810352C02B145FF304FCBD5BEF4F7AA9F:1" [4]="013720F40B99D6BCF6F08BD7271523EBB49:1" [5]="01C894A55EBCB6048A745B37EC2D989F102:1" [6]="030B46D53696C8889910EE0F9EB42CEAE97:4" [7]="03126B56153F0564F4A6ED6E734604C67E8:2" [8]="043196099707FCB0C01F8C2111086A92A0B:1" [9]="0452CABBEF8438F358F0BD8089108D0910E:5" [10]="0490255B206A2C0377EBD080723BF72DDAE:2" [11]="05AD1141C41237E061460DB5CA5412C1A48:4" [12]="05C1D058E4439F8F005EFB32E7553E6AA5B:1" [13]="067AF515CC712AC4ACA012311979DBC7C9A:2")
    

    假设 OP 想要从变量 $temp 填充数组,并假设 $temp 中的空白由换行符而不是空格组成:

    $ mapfile -t myArr <<< "${temp}"
    $ typeset -p myArr
    declare -a x=([0]="002C3CADF9FC86069F09961B10E0EDEFC45:1" [1]="003BE35BD9466D19258E79C8665AFB072F6:1" [2]="0075B2ADF782F9677BDDF8CC5778900D986:8" [3]="00810352C02B145FF304FCBD5BEF4F7AA9F:1" [4]="013720F40B99D6BCF6F08BD7271523EBB49:1" [5]="01C894A55EBCB6048A745B37EC2D989F102:1" [6]="030B46D53696C8889910EE0F9EB42CEAE97:4" [7]="03126B56153F0564F4A6ED6E734604C67E8:2" [8]="043196099707FCB0C01F8C2111086A92A0B:1" [9]="0452CABBEF8438F358F0BD8089108D0910E:5" [10]="0490255B206A2C0377EBD080723BF72DDAE:2" [11]="05AD1141C41237E061460DB5CA5412C1A48:4" [12]="05C1D058E4439F8F005EFB32E7553E6AA5B:1" [13]="067AF515CC712AC4ACA012311979DBC7C9A:2")
    

    【讨论】:

    • 不需要用空格替换换行符。不过,您可能希望确保值中没有 DOS 回车符 (tr -d '\015')
    • array=$( $(anything) ) 不是一个好的做法——您不希望将仅包含 * 的行替换为当前目录 f/e 中的文件名列表。按照本练习结束时的建议,最好使用mapfile
    • 和triple 的评论一样,我不知道tr 在这里完成了什么;默认值IFS 中都存在换行符和空格。
    • triplee/Charles Duffy - 感谢评论回复:tr ... 在cygwin/bash 下运行我的测试,出于某种原因,\n 被选为数据;已更新答案
    猜你喜欢
    • 2014-12-20
    • 2016-03-15
    • 2021-01-04
    • 2014-05-02
    • 2021-03-05
    • 1970-01-01
    • 2021-03-29
    • 2020-10-20
    • 1970-01-01
    相关资源
    最近更新 更多