【问题标题】:Unable to add element to array in bash无法在bash中将元素添加到数组
【发布时间】:2014-05-06 15:38:51
【问题描述】:

我有以下问题。假设$@ 仅包含有效文件。变量file 包含当前文件的名称(我当前“打开”的文件)。然后变量element包含file:function格式的数据。

现在,当变量元素不为空时,应该将其放入数组中。这就是问题所在。如果我回显element,它包含的正是我想要的,虽然它没有存储在数组中,所以 for 循环不会打印出任何东西。

我已经编写了两种尝试将元素插入数组的方法,但都不起作用。你能告诉我,我做错了什么吗?

我正在使用 Linux Mint 16。

#!/bin/bash

nm $@ | while read line
do
  pattern="`echo \"$line\" | sed -n \"s/^\(.*\):$/\1/p\"`"
  if [ -n "$pattern" ]; then
    file="$pattern"  
  fi
  element="`echo \"$line\" | sed -n \"s/^U \([0-9a-zA-Z_]*\).*/$file:\1/p\"`"
  if [ -n "$element" ]; then
    array+=("$element")
    #array[$[${#array[@]}+1]]="$element"
    echo element - "$element"
  fi
done

for j in "${array[@]}"
do
  echo "$j"
done

【问题讨论】:

  • 始终使用$(…) 而不是反引号。
  • nm 有一些选项可以在每一行打印文件名(通常是-r-R,IIRC)。这将为您节省大部分操作工作。
  • 将 shell 跟踪调试功能 set -vx(或简化输出)与 set -x 结合使用。您将看到如何评估变量,然后通常很容易修复。此外,加入 90 年代并停止使用 back-tics 进行命令替换。 var=$(cmd_produces_output),不是 100% 可移植的,但更容易阅读和嵌套。最后,仅当您需要在 cmd 中进行变量扩展时,才在 sed cmds 上使用 dbl-quotes。正常使用单引号,然后避免转义它们。祝你好运。
  • 在任何情况下,您都在子shell中设置array的值,因此没有为以下for循环定义。
  • 是的,我知道一些选项。实际上我使用了选项-o,正如你所说,它在每一行上打印文件名。但我发现禁止对 nm 使用任何选项。我很抱歉,但我不明白 $(...)。你的意思是我应该将第 5 行替换为 pattern=$(echo "$line"| ...) 吗?与第 9 行相同。

标签: arrays linux bash


【解决方案1】:

您的问题是while 循环在子shell 中运行,因为它是管道中的第二个命令,因此在该循环中所做的任何更改在循环退出后都不可用。

您有几个选择。我经常使用{}command grouping

nm "$@" |
{
while read line
do
    …
done
for j in "${array[@]}"
do
    echo "$j"
done
}

bash,也可以使用process substitution

while read line
do
    …
done < <(nm "$@")

另外,最好使用$(…) 代替反引号`…`(不仅仅是因为将引号返回到降价文本中很困难!)。

您的线路:

element="`echo \"$line\" | sed -n \"s/^U \([0-9a-zA-Z_]*\).*/$file:\1/p\"`"

可以写成:

element="$(echo "$line" | sed -n "s/^U \([0-9a-zA-Z_]*\).*/$file:\1/p")"

甚至:

element=$(echo "$line" | sed -n "s/^U \([0-9a-zA-Z_]*\).*/$file:\1/p")

当您需要嵌套它们时,它真的很有帮助。例如,要列出与找到gcc 的位置相邻的lib 目录:

ls -l $(dirname $(dirname $(which gcc)))/lib

ls -l `dirname \`dirname \\\`which gcc\\\`\``/lib

我知道哪个更容易!

【讨论】:

  • 哦,非常感谢,我没有意识到subshel​​l。实际上这是我的第一个脚本。所以现在我会知道的。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 2019-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-11
  • 2018-01-21
相关资源
最近更新 更多