我有以下问题。我们假设$@
仅包含有效文件。变量file
包含当前文件的名称(我当前“打开”的文件)。然后变量element
包含格式file:function
。
现在,当变量元素不为空时,应将其放入数组中。这就是问题所在。如果我回显element
,它包含我想要的内容,虽然它没有存储在数组中,所以对于循环不打印任何东西。
我写过两种尝试将元素插入数组的方法,但都不起作用。你能告诉我,我做错了什么,拜托?
我正在使用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
答案 0 :(得分:13)
您的问题是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")
当您需要嵌套时,这确实很有帮助。例如,要列出与lib
所在位置相邻的gcc
目录:
ls -l $(dirname $(dirname $(which gcc)))/lib
VS
ls -l `dirname \`dirname \\\`which gcc\\\`\``/lib
我知道哪个更容易找到!