Function Sed:snake-case函数

Function Sed:snake-case函数,function,sed,case-conversion,Function,Sed,Case Conversion,我需要一个sed脚本来自动将C函数转换为小写 到目前为止,我所看到的是以下内容,它将用下划线分隔驼峰大小写单词,但它不会降低它们的大小写,它会影响所有内容 sed -i -e 's/\([a-z0-9]\)\([A-Z]\)/\1_\L\2/g' `find source/ -type f` 如何使其仅适用于函数?即,仅在后跟字符“(”的字符串上 还有,我需要什么使字符串小写 例如,如果我有以下代码: void destroyPoolLender(PoolLender *lender) {

我需要一个sed脚本来自动将C函数转换为小写

到目前为止,我所看到的是以下内容,它将用下划线分隔驼峰大小写单词,但它不会降低它们的大小写,它会影响所有内容

sed -i -e 's/\([a-z0-9]\)\([A-Z]\)/\1_\L\2/g' `find source/ -type f`
如何使其仅适用于函数?即,仅在后跟字符“(”的字符串上

还有,我需要什么使字符串小写

例如,如果我有以下代码:

void destroyPoolLender(PoolLender *lender)
{
    while (!isListEmpty(&lender->pools)) {
        MemoryPool *myPool = listPop(&this->pool);

        if (pool->inUse) {
            logError("%s memory pool still in use. Pool not released.", pool->lenderName);
        } else {
            free(pool);
        }
    }
    listDestroy(&this->pool);
}
一旦转换,它应该是这样的:

void destroy_pool_lender(PoolLender *lender)
{
    while (!is_list_empty(&lender->pools)) {
        MemoryPool *myPool = list_pop(&this->pool);

        if (pool->inUse) {
            log_error("%s memory pool still in use. Pool not released.", pool->lenderName);
        } else {
            free(pool);
        }
    }
    list_destroy(&lender->pools);
}

请注意myPool是如何未被触及的,因为它不是一个函数名。

我们可以使用sed来实现这一点。诀窍是将所有内容匹配到并包括
)作为捕获组2,并使用
\l
而不是
\l
,只对第一个匹配的字符进行降级:

s/\([a-z0-9]\)\([a-Z][a-Za-z0-9]*(\)/\1\Ul\2/
我们不能只使用
/g
修饰符,因为后续替换可能会重叠,所以在循环中使用它:

!/bin/sed-rf
:循环
s/([a-z0-9])([a-Z][a-Za-z0-9]*\()/\1\Ul\2/
特卢普
(我对GNU使用了
-r
,以减少所需的反斜杠数量)

进一步简化是匹配非单词边界;这样就不需要两个捕获组:

!/bin/sed-rf
:循环
s/\B[A-Z]\w*\(/\ul)&/
特卢普
演示:
$sed-r':循环;s/\B[A-Z]\w*\(/\ul&/;tloop'\

bash的解决方案。它通过
nm
命令使用对象文件中的信息。请参阅
man-nm

要从源文件创建目标文件,您需要为每个源文件运行
gcc
-c
选项(可能您已经有了它们,由
make
命令创建。然后,您可以跳过此步骤):

用法:/code>/convert.sh one.o two.o

#!/bin/bash

# store original function names to the variable.
orig_func_names=$(
    # get list symbols from all object files
    nm -f sysv "$@" |
    # picks the functions and removes all information except names.
    sed -n '/FUNC/s/\s.*//p' |
    # selects only functions, which contain the uppercase letter in the name.
    sed -n '/[A-Z]/p'
);

# convert camel case names to snake case names and store new names to the variable.
new_func_names=$(sed 's/[A-Z]/_\l&/g' <<< "$orig_func_names")

# create file, containing substitute commands for 'sed'. 
# Example of commands from this file:
# s/\boneTwo\b/one_two/g
# s/\boneTwoThree\b/one_two_three/g
# etc. One line to the each function name.
paste -d'/' <(printf 's/\\b%s\\b\n' ${orig_func_names}) <(printf '%s/g\n' ${new_func_names}) > command_file.txt

# do converting
# change object file extenstions '.o' to C source - '.c' file extensions.
# were this filenames: one.o two.o three.o
# now they are: one.c two.c three.c
# this 'sed' command creates backup for the each file and change the source files. 
sed -i_backup -f command_file.txt "${@/.o/.c}"
文件
two.c

#include <stdio.h>

int two() {
    return 0; 
}

int twoThree() {
    two();
    return 0;
}   

int twoThreeFour() {
    twoThree();
    return 0;    
}   
#include <stdio.h>

int two() {
    return 0;  
}

int two_three() {
    two();
    return 0;
}   

int two_three_four() {
    two_three();
    return 0;    
}  
文件
two.c

#include <stdio.h>

int two() {
    return 0; 
}

int twoThree() {
    two();
    return 0;
}   

int twoThreeFour() {
    twoThree();
    return 0;    
}   
#include <stdio.h>

int two() {
    return 0;  
}

int two_three() {
    two();
    return 0;
}   

int two_three_four() {
    two_three();
    return 0;    
}  
#包括
int二(){
返回0;
}
int two_three(){
二();
返回0;
}   
int two_3; u four(){
二(三);
返回0;
}  

我认为您应该通过管道将
sed
的输出设置为小写,并使用
tr
将输入数据和预期结果发布。输入数据是一个大约70k行代码的C代码库,其函数以驼峰大小写风格编写。预期结果是将这些函数转换为小写的蛇形大小写风格。其余的f不得触摸代码。
#include <stdio.h>

int two() {
    return 0;  
}

int two_three() {
    two();
    return 0;
}   

int two_three_four() {
    two_three();
    return 0;    
}