【问题标题】:How can I skip empty lines in bash with mapfile / readarray?如何使用 mapfile / readarray 跳过 bash 中的空行?
【发布时间】:2014-10-05 20:57:22
【问题描述】:
foo()
{

  mapfile -t arr <<< "${1}"

  for i in "${!arr[@]}"
  do
    if [ -z "${arr[$i]}" ]
    then
      unset arr[$i]
    fi
  done

}

当我传递一个包含一些内容的变量(基本上是一个大字符串)时,我想:

  1. 将第一个空格之前的第一个单词解释为键,第一个空格之后的所有内容都将成为我的关联数组中该键的条目
  2. 跳过空行或仅包含换行符的行

示例(为了简洁,不包括空行)

google https://www.google.com
yahoo https://www.yahoo.com
microsoft https://www.microsoft.com

数组应该是这样的

[ google ] == https://www.google.com
[ yahoo ] == https://www.yahoo.com
[ microsoft ] == https://www.microsoft.com

我在 bash 手册中没有找到任何好的解决方案来解决这两个点,你看到的函数 foo 是一种创建数组的 hack,然后才遍历整个数组并删除字符串为空的条目。

所以第 2 点得到了一个解决方案,可能是一个效率低下的解决方案,但它有效,但第 1 点仍然没有一个好的解决方案,替代解决方案是在使用 read 迭代时创建一个数组,到目前为止据我所知。

你知道如何改进吗?

【问题讨论】:

  • 这也是我不愿意使用read 的原因,read 通常会随机排列条目并且不会复制原始顺序,mapfile 通常会将内容保存在与原始字符串/文件的顺序相同。
  • mapfile 将所有内容保持在原始顺序,因为它不会创建关联数组。 read 与您构建的数组无关,但可能您实际上是在使用关联数组时一次一个地添加项目。
  • @chepner 这就是我想要的,一个mapfile,它创建了我的帖子中描述的关联数组,我对这两个点是否可行没有最后的决定只是来自 bash 的内置命令。

标签: arrays bash associative-array


【解决方案1】:

mapfile 不构建关联数组(尽管如果可以的话,#2 的最简单解决方案是简单地过滤输入,例如,grep:mapfile -t arr &lt; &lt;(echo "$1" | grep -v "^$")

使用read 回退到显式循环,使用=~ 运算符匹配并跳过空白行。

declare -A arr
while read key value; do
    if [[ $value =~ "^\s*$" ]]; then  # Or your favorite regex for skipping blank lines
        continue
    fi
    arr["$key"]="$value"
done <<< "$1"

您也可以使用 grep 跳过空白行,即使使用 while 循环:

declare -A arr
while read key value; do
   arr["$key"]="$value"
done < <(echo "$1" | grep '^\s*$')

【讨论】:

  • 是的,这是我的 fallback 解决方案,可能使用自定义IFS,具体取决于我得到的输入类型,所以这不适用于 bash 吗?
猜你喜欢
  • 2017-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多