我一直在编写一个脚本来搜索定义的名称,然后获取它们的十六进制值并将它们放在列表中。一旦我有名单,我将尝试搜索" #define [name]"使用-w确保完全匹配,然后awk' {print $ 3}'获取十六进制值。
然而,如果该行类似于
,则它可以工作a.h:#define [name] 0x000
但如果它与
相似则不起作用a.h: #define [name] 0x000
我该如何解决这个问题?我试过这个
grep -nrw "\s*#define[[:space:]]*$p" . --include=*.h | awk '{ print $3 }'
我认为\s*
会忽略#define
之前的前导空格,但它不会。我做错了吗?
答案 0 :(得分:1)
如果它是最后一个元素,您可以随时使用
... | awk '{print $NF}'
你也可以在awk中过滤
awk '/#define/{print $NF}'
这将在与" #define"
匹配后打印第二个字段awk '{for(i=1;i<NF-1;i++) if($i~"#define") print $(i+2)}'
答案 1 :(得分:1)
在Linux上,这可能完美无缺:
grep -Poinr "#define\s+\[.*?\K[0-9a-f]+x[0-9a-f]+" . --include=*.h
答案 2 :(得分:0)
grep
仍匹配您想要的行,但行号和#define
之间的空格使其成为单独的awk
字段。
find -iname '*.[ch]' -exec sed -nse 's/.*\(#define\s*[a-zA-Z0-9_]*\)\(.*\)/\1: \2/p' {} +
如果您希望分别对每个符号的全文运行此搜索,请将[a-zA-Z0-9_]*
替换为您的$p
。 (一次提取所有定义的列表然后再搜索它会更快。)
我使用sed -s
以防您想要添加sed命令来打印行号。您正在使用grep -n
,然后使用awk丢弃行号,所以我想您可能正在展示一个如何使用grep
输出的简要示例。
您还可以使用GNU grep -o
仅打印与您的模式匹配的行部分。然后,不是让您的模式匹配空格,而是grep输出行总是看起来像
number:#define ...
像你的awk命令一样期待。
答案 3 :(得分:0)
让我们把它作为我们的样本输入:
$ cat a.h
other name 0x100
#define name 0x000
#define name 0x001
$ p=name; awk -v v="$p" '$1=="#define" && $2==v{print $3}' a.h
0x000
0x001
如果我们想要求打印值是十六进制数:
$ p=name; awk -v v="$p" '$1=="#define" && $2==v && $3 ~ /^0x[[:xdigit:]]+$/{print $3}' a.h
0x000
0x001
$ p=name; sed -nE "s/\s*#define\s+$p\s+([[:xdigit:]]*)/\1/p" a.h
0x000
0x001
如果我们想对我们匹配的内容更加严格:
$ p=name; sed -nE "s/\s*#define\s+$p\s+(0x[[:xdigit:]]*)$/\1/p" a.h
0x000
0x001
前导空格的存在并不会改变字段的awk编号:
$ echo ' 1 2' | awk '{for (i=1;i<=NF;i++)printf "field %s = %s\n",i,$i;}'
field 1 = 1
field 2 = 2
$ echo '1 2' | awk '{for (i=1;i<=NF;i++)printf "field %s = %s\n",i,$i;}'
field 1 = 1
field 2 = 2