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