【问题标题】:Reading a file into an associative array in Bash将文件读入 Bash 中的关联数组
【发布时间】:2016-11-02 18:52:42
【问题描述】:

我正在尝试使用 Bash 脚本将结构化文件的信息读入关联数组。该文件的每一行都包含一个人的姓名及其地址,用“|”分隔。例如:

person1|address of person1
person2|address of person2
...
personN|address of personN

我尝试使用下面的脚本来执行此操作。在 WHILE 循环中,正在打印信息。但是,在 FOR 循环中不会打印信息。似乎信息没有存储在 WHILE 循环之外的关联数组中。

我做错了什么?为什么这不起作用?有没有更有效的方法来做到这一点?

#!/bin/bash
declare -A address
cat adresses.txt | while read line
do
    name=`echo $line | cut -d '|' -f 1`
    add=`echo $line | cut -d '|' -f 2`
    address[$name]=$add
    echo "$name - ${address[$name]}"
done

for name in ${!address[*]}
do
    echo "$name - ${address[$name]}"
done

【问题讨论】:

标签: arrays linux bash shell


【解决方案1】:

cut的错误和无用用法

#!/bin/bash
declare -A address
while IFS=\| read name add
do
    address[$name]=$add
done < adresses.txt

for name in ${!address[*]}
do
    echo "$name - ${address[$name]}"
done

【讨论】:

  • OP 代码中的 cut 效率低下,没有错。然而,cat 既无用又错误。
  • 对不起。我在剧本中犯了一个错误。但是我已经修复了原始帖子。 cut 命令工作正常。而且我可以在 WHILE 循环中访问关联数组的信息。但是,我无法在 FOR 循环中访问它。
【解决方案2】:
cat addresses.txt | while read line
do
    ...
done

管道中的外壳命令在子外壳中执行。子 shell 中设置的变量在父 shell 中不可见。

您可以通过将管道替换为重定向来解决此问题。

while read line
do
    ...
done < addresses.txt

【讨论】:

  • 是的!这就是问题所在!但是,现在我遇到了另一个问题。如果人名有空格,则 FOR 循环不能正常工作。
【解决方案3】:

扩展接受的答案以解决 OP 的评论:

#!/bin/bash
declare -A address
while IFS='|' read name add
do
    address[$name]=$add
    echo "$name - ${address[$name]}"
done < adresses.txt

for name in "${!address[@]}"
do
    echo "$name - ${address[$name]}"
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 2014-10-04
    • 2014-06-19
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2016-09-07
    相关资源
    最近更新 更多