如何查找目录及子目录下的.c文件并按指定格式输出函数定义?
解决C文件函数名提取的格式问题
我来帮你搞定这个需求!你原来的命令主要有两个问题:一是grep的匹配规则太宽泛,会误抓很多不是函数定义的内容(比如注释里的括号、函数调用);二是文件路径和函数行的关联逻辑有问题,同一个文件的多个函数只有第一个会带路径,后面的就直接裸输出了,不符合你想要的格式。
给你两个精准实现预期效果的方案:
方案一:用awk处理(推荐,更灵活)
这个方案能自动识别同一个文件的函数,只在第一个函数前打印文件名,后续函数行对齐输出:
find "$1" -type f -name "*.c" -exec awk ' # 匹配常见的函数返回类型,确保是函数定义行 /^[[:space:]]*(void|int|char|float|double|long|unsigned|struct|enum|FILE\*)/ && /[[:space:]]*\(/ { # 如果当前文件和上一个处理的文件不同,打印文件名前缀 if (FILENAME != prev_file) { print FILENAME ": " $0 prev_file = FILENAME } else { # 同一个文件的后续函数,只输出函数内容(前面加空格对齐) print " " $0 } } ' {} \;
逻辑说明:
- awk的正则先匹配C语言常见的返回类型(包括指针类型比如
FILE*),再检查是否有函数的括号(),这样能精准定位函数定义行,避免误匹配 - 用
prev_file变量记录上一个处理的文件名,确保同一个文件的多个函数只有第一行带路径,后续行对齐输出
方案二:用shell循环+grep+sed实现
如果更习惯用grep,也可以用这个方案:
find "$1" -type f -name "*.c" | while read -r file; do # 先打印当前文件名加冒号 echo -n "$file: " # 用grep匹配函数行,sed把除第一行外的所有行前面加空格对齐 grep -E '^[[:space:]]*(void|int|char|float|double|long|unsigned|struct|enum|FILE\*).*\(' "$file" | sed '1!s/^/ /' done
逻辑说明:
- 用while循环遍历每个找到的.c文件,先输出文件名前缀
- grep用扩展正则匹配函数定义行,sed处理格式:
1!s/^/ /表示除了第一行,其他行开头加空格,实现同一个文件的函数行对齐
补充提示:
如果你的代码里有更复杂的函数定义(比如typedef的自定义类型、函数指针作为返回值),可以根据实际情况扩展正则里的返回类型部分,比如加上你的自定义类型关键词。
内容的提问来源于stack exchange,提问作者승기유
相关产品推荐
相关产品推荐

