使用 awk 解析 nm 命令的输出 - Linux Bash
parsing output from nm command with awk - Linux Bash
我正在进行一些代码优化,我会检查我的函数的大小而不是读取巨大的反汇编文件。在 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 }')
为了确保一切正常,我检查了 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
为什么大小为“1”以及为什么我能够像在数组中一样打印每个元素。看起来输出的行尾仍然有一个 'space' ' '。是否有任何带有 awk 的正则表达式可以避免将分隔符字段包含到数组中?
感谢您的帮助!!
回答后编辑
read -a FUNCSIZE <<< $(nm --size-sort $OBJFILEPATH.o | awk '{print }')
SIZE=${#FUNCSIZE[*]}
for((i=0; i<SIZE; i++))
do
echo ${FUNCSIZE[$i]}
done
按照你的写法,FUNCSIZE
不是一个数组,而是一个常规变量。
为 read
添加 -a
标志:
read -a FUNCSIZE <<< $(nm --size-sort $OBJFILEPATH.o | awk '{print }')
请注意,不建议对用户定义的变量使用全部大写的名称,以 avoid conflicts (and confusion) with environmental variables and special shell variables。
(感谢 @mklement0 的提示和链接!)
从您的评论来看,这可能是您真正想要的:
$ cat tst.awk
{
size = strtonum("0x")
sub(/^([^[:space:]]+[[:space:]]+){2}/,"")
name = [=10=]
}
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
上面对 strtonum() 使用 GNU awk 并且在这两个输入文件上 运行:
$ 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 ...
。
我正在进行一些代码优化,我会检查我的函数的大小而不是读取巨大的反汇编文件。在 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 }')
为了确保一切正常,我检查了 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
为什么大小为“1”以及为什么我能够像在数组中一样打印每个元素。看起来输出的行尾仍然有一个 'space' ' '。是否有任何带有 awk 的正则表达式可以避免将分隔符字段包含到数组中?
感谢您的帮助!!
回答后编辑
read -a FUNCSIZE <<< $(nm --size-sort $OBJFILEPATH.o | awk '{print }')
SIZE=${#FUNCSIZE[*]}
for((i=0; i<SIZE; i++))
do
echo ${FUNCSIZE[$i]}
done
按照你的写法,FUNCSIZE
不是一个数组,而是一个常规变量。
为 read
添加 -a
标志:
read -a FUNCSIZE <<< $(nm --size-sort $OBJFILEPATH.o | awk '{print }')
请注意,不建议对用户定义的变量使用全部大写的名称,以 avoid conflicts (and confusion) with environmental variables and special shell variables。
(感谢 @mklement0 的提示和链接!)
从您的评论来看,这可能是您真正想要的:
$ cat tst.awk
{
size = strtonum("0x")
sub(/^([^[:space:]]+[[:space:]]+){2}/,"")
name = [=10=]
}
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
上面对 strtonum() 使用 GNU awk 并且在这两个输入文件上 运行:
$ 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 ...
。