使用awk解析nm命令的输出 - Linux Bash

时间:2016-08-02 16:11:26

标签: linux bash shell awk nm

我正在进行一些代码优化,我会检查我的函数的大小,而不是阅读巨大的反汇编文件。在Debug上编译之后,我使用nm命令来读取.o。我们得到了这个:

nm --size-sort $OBJFILEPATH.o

000000000000000b r __PRETTY_FUNCTION__.6473
0000000000000017 t extract_h
0000000000000036 t L_mult
000000000000003a t sature32
0000000000000042 t L_mac
0000000000000048 t L_add
000000000000005c t Mac16x11
0000000000000077 t L_shl
0000000000000083 t L_shr
00000000000000df T G729Convolve
0000000000000114 T G729Residu
00000000000001bc T G729Syn_filt_L_H
00000000000001bc T G729Syn_filt_L_SUBFR

现在,在一个bash脚本中,我想只解析第一列,每行代表bash中的一个数组元素。

我的命令是:

read FUNCSIZE <<< $(nm --size-sort $OBJFILEPATH.o | awk '{print $1}')

为了确保一切正常,我检查了我的FUNCSIZE数组的大小。

SIZE=${#FUNCSIZE[@]}
echo size is $SIZE
for s in $FUNCSIZE
do
    echo $s
done

我得到了这个输出:

size is 1
000000000000000b
0000000000000017
0000000000000036
000000000000003a
0000000000000042
0000000000000048
000000000000005c
0000000000000077
0000000000000083
00000000000000df
0000000000000114
00000000000001bc
00000000000001bc

为什么尺寸是&#39; 1&#39;为什么我能够像在阵列中一样打印每个元素。似乎输出仍然有一个空间&#39; &#39; &#39;在行尾。是否有任何带有awk的RegEx会避免将分隔符字段包含在数组中?

感谢您的帮助!!

在回答后编辑

read -a FUNCSIZE <<< $(nm --size-sort $OBJFILEPATH.o | awk '{print $1}')
SIZE=${#FUNCSIZE[*]}
for((i=0; i<SIZE; i++))
do
    echo ${FUNCSIZE[$i]}
done

2 个答案:

答案 0 :(得分:2)

编写它的方式,FUNCSIZE不是数组,而是常规变量。

-a添加read标记:

read -a FUNCSIZE <<< $(nm --size-sort $OBJFILEPATH.o | awk '{print $1}')

请注意,不建议对avoid conflicts (and confusion) with environmental variables and special shell variables使用用户定义变量的全大写名称。

(感谢@mklement0提供了提示和链接!)

答案 1 :(得分:1)

这听起来像你的评论,这可能是你真正想要的:

$ cat tst.awk
{
    size = strtonum("0x"$1)
    sub(/^([^[:space:]]+[[:space:]]+){2}/,"")
    name = $0
}
NR==FNR { oldSize[name] = size; next }
{
    newSize[name] = size
    if ( name in oldSize ) {
        if ( oldSize[name] < newSize[name] ) {
            bigger[name]
        }
        else if ( oldSize[name] > newSize[name] ) {
            smaller[name]
        }
    }
    else {
        added[name]
    }
}
END {
   print "Got bigger:"
   for (name in bigger) print "\t" name, oldSize[name], "->", newSize[name]

   print "Got smaller:"
   for (name in smaller) print "\t" name, oldSize[name], "->", newSize[name]

   print "Added:"
   for (name in added) print "\t" name

   print "Deleted:"
   for (name in oldSize) if ( !(name in newSize) ) print "\t" name
}

$ gawk -f tst.awk <(cat file1) <(cat file2)
Got bigger:
    Mac16x11 92 -> 93
Got smaller:
    L_mac 66 -> 65
Added:
    extract_h
Deleted:
    G729Residu

以上使用GNU awk for strtonum()并在这两个输入文件上运行:

$ cat file1
000000000000000b r __PRETTY_FUNCTION__.6473
0000000000000036 t L_mult
000000000000003a t sature32
0000000000000042 t L_mac
0000000000000048 t L_add
000000000000005c t Mac16x11
0000000000000077 t L_shl
0000000000000083 t L_shr
00000000000000df T G729Convolve
0000000000000114 T G729Residu
00000000000001bc T G729Syn_filt_L_H
00000000000001bc T G729Syn_filt_L_SUBFR

$ cat file2
000000000000000b r __PRETTY_FUNCTION__.6473
0000000000000017 t extract_h
0000000000000036 t L_mult
000000000000003a t sature32
0000000000000041 t L_mac
0000000000000048 t L_add
000000000000005d t Mac16x11
0000000000000077 t L_shl
0000000000000083 t L_shr
00000000000000df T G729Convolve
00000000000001bc T G729Syn_filt_L_H
00000000000001bc T G729Syn_filt_L_SUBFR

只需将每个cat file替换为相应的nm ...