按字母顺序对C原型排序的单向方式

按字母顺序对C原型排序的单向方式,c,sorting,unix,function-prototypes,C,Sorting,Unix,Function Prototypes,假设您有一个C函数原型列表,每行一个,如 void foo(void); struct baz *zap(void (*callback)(void)); long long blurb(long i); long double sinus(long double arg); sometype_t somefunc(void); 按函数名排序,结果为 long long blurb(long i); void foo(void); long double sinus(long doub

假设您有一个C函数原型列表,每行一个,如

void   foo(void);
struct baz *zap(void (*callback)(void));
long long blurb(long i);
long double sinus(long double arg);
sometype_t somefunc(void);
按函数名排序,结果为

long long blurb(long i);
void   foo(void);
long double sinus(long double arg);
sometype_t somefunc(void);
struct baz *zap(void (*callback)(void));
就我所阅读的sort(1)手册而言,这不能使用-k选项进行排序,因为函数标识符有时是第二个单词,有时是第三个单词(让我们忽略函数标识符更靠右的情况,例如在拼写结构时)


但我知道函数标识符是第一个('token on the line.有人知道unixy排序方法吗?unixy:=一个单行过滤器/管道。我可能会想出一个难看的perl解决方案,删除不感兴趣的左侧部分,排序并恢复左侧部分,但这离一行还差得远。

使用
awk
tr
cut
排序

tr -s ' ' file | cut -d '(' -f 1 | awk '{print($NF" "$0)}' | cut -d ' ' -f1 | tr -d '*' | sort
  • 压缩空间重复
  • 使用(分隔符)从行中剪切第一个字段
  • 首先获取最后一个字段、函数名和副本
  • 使用空格分隔符仅剪切第一个字段
  • 删除所有*,指针返回字符
  • 分类
  • 但我知道函数标识符是行中第一个“(”标记之前的字符串

    我执行此类排序任务的通常方法是使用
    sed
    和一个好的正则表达式,在输入中插入一个唯一的分隔符,我以后可以使用
    sort
    。排序后,可以删除分隔符。因此:

  • 在函数标识符前面插入
  • 使用
    作为分隔符)按第二列排序
  • 从行中删除第一个
  • 以下是:

    sed 's/\([a-zA-Z0-9_]*(\)/(\1/' | sort -t'(' -k2 | sed 's/(//'
    
    通过以下输入:

    void   foo(void);
    struct baz *zap(void (*callback)(void));
    long long blurb(long i);
    long double sinus(long double arg);
    sometype_t somefunc(void);
    
    :

    使用:


    为什么要按第一个字母而不是功能对函数进行分组?也许可以使用awk将函数名交换/复制到第一个位置,然后通过管道进行排序,这样您就可以排序`foo:void foo(void)。。。“当然,在perl中,每件事都可以是一行,只是有时这是一条很长的行!@Lundin,因为函数已经有了名称前缀,如fooStart、fooStop、fooGet、fooSet。此外,“相同的功能”是一个非常任意和模糊的标准。按字母顺序插入原型的位置没有歧义。在这种情况下,顺序对编译器来说并不重要,我喜欢硬性规则。请注意,标准C函数
    signal()
    有一个类似
    void(*signal(int-sig,void(*func)(int))(int)的原型
    这与您的期望不符。在一行代码中没有简单的方法可以做到这一点-这不是一个简单的问题,因为C语法并不简单。事实上,我认为在多行脚本中没有简单的方法可以做到这一点-简单地分析行以提取函数名是一项艰巨的工作。这只剩下func这个想法是按行对整个输入进行排序。
    long long blurb(long i);
    void   foo(void);
    long double sinus(long double arg);
    sometype_t somefunc(void);
    struct baz *zap(void (*callback)(void));
    
    perl -pE 'm!([a-zA-Z_][a-zA-Z0-9_]*)\(! && print "$1:"' | # decorate
    sort |                                                    # sort
    perl -pE 's!^([a-zA-Z_][a-zA-Z0-9_]*):!!'                 # undecorate