我一直在编写一个 bash 脚本来搜索定义的名称,然后获取它们的十六进制值并将它们放入列表中。一旦获得名称列表,我将尝试使用 -w 搜索“#define [name]”以确保完全匹配,然后使用 awk '{ print $3 }' 获取十六进制值。
但是,如果头文件中的行类似于
a.h:#define [name] 0x0001
但如果它类似于
a.h: #define [name] 0x0001
我该如何解决这个问题?我试过这个
grep -nrw "\s*#define[[:space:]]*$p" . --include=*.h | awk '{ print $3 }'
我认为\s*
之前会忽略前导空格#define
,但事实并非如此。难道我做错了什么?
答案1
只需使用awk
(使用grep
对我来说似乎是多余的,因为awk
已经可以匹配正则表达式):
awk '$0~/\s*\#define\s*\[.*\]\s*.*/ {print $3}' *.h
更详细地分析该表达式:
$0 ~ /regexp/ # look for the regular expression in the record
\s* # whitespace, any number of times
\#define # literal string, '#' has to be scaped
\s* # same as above
.* # any character, any number of times, this is
# your hex code and you can refine the regex here
{ print $3 } # print the third field if the record matches
要递归地运行此操作,例如
mkdir -p a/b/c
echo " #define [name] 0x0001" > a/a.h
echo " #define [name] 0x0002" > a/b/b.h
echo " #define [name] 0x0003" > a/b/c/c.h
tree
.
└── a
├── a.h
└── b
├── b.h
└── c
└── c.h
3 directories, 3 files
由于awk
需要给出要操作的文件列表,您可以:
find . -type f -name "*.h" \
-exec awk '$0~/\s*\#define\s*\[.*\]\s*.*/ {print $3}' {} \;
0x0002
0x0003
0x0001
答案2
用于grep -o
仅打印该行的匹配部分。
显然\s
再次取出该部分,因为您不需要该部分。