Arrays 无法在bash中将元素添加到数组中

Arrays 无法在bash中将元素添加到数组中,arrays,linux,bash,Arrays,Linux,Bash,我有以下问题。假设$@只包含有效文件。变量file包含当前文件的名称(我当前“打开”的文件)。然后变量元素包含文件:函数格式的数据 现在,当variable元素不为空时,应该将其放入数组中。这就是问题所在。若我回显元素,它正好包含我想要的内容,尽管它并没有存储在数组中,所以for cycle不会打印出任何内容 我写了两种方法尝试将元素插入数组,但都不起作用。你能告诉我,我做错了什么吗 我使用的是LinuxMint16 #!/bin/bash nm $@ | while read line do

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

现在,当variable元素不为空时,应该将其放入数组中。这就是问题所在。若我回显
元素
,它正好包含我想要的内容,尽管它并没有存储在数组中,所以for cycle不会打印出任何内容

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

我使用的是LinuxMint16

#!/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

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

你有几个选择。我经常使用
{
}
来:

bash
中,您还可以使用:

可以这样写:

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
vs


我知道我觉得哪个更容易

始终使用
$(…)
优先于反引号。有
nm
选项可以在每行打印文件名(通常是
-r
-r
,IIRC)。这将节省您正在进行的大部分操作工作。将shell跟踪调试功能
set-vx
(或简化输出)与
set-x
一起使用。您将看到变量是如何计算的,然后通常很容易修复。另外,加入90年代,停止使用back tics替换命令
var=$(cmd\u产生\u输出)
,不是100%可移植的,但更易于阅读和嵌套。最后,当需要在cmd内部进行变量扩展时,仅在sed cmd上使用dbl引号。通常使用单引号,然后避免转义它们。祝你好运。在任何情况下,你都是在子shell中设置
array
的值,因此它不是为以下
for
循环定义的。是的,我知道一些选项。实际上,我使用了选项-o,正如您所说,它会在每一行打印文件名。但我发现禁止使用任何选项来进行nm。很抱歉,我不明白$(…)。您的意思是我应该替换模式=$(echo“$line”|…)的第5行吗?第九行也一样。哦,非常感谢,我没有意识到。实际上这是我的第一个剧本。现在我知道了。再次感谢你。
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")
ls -l $(dirname $(dirname $(which gcc)))/lib
ls -l `dirname \`dirname \\\`which gcc\\\`\``/lib