Grep 并忽略前导空格

Grep 并忽略前导空格

我一直在编写一个 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再次取出该部分,因为您不需要该部分。

相关内容