如何将跨多行的typedef合并为单行?

时间:2016-02-11 04:34:21

标签: python bash

我希望将使用bash命令或python的typedef跨多行合并为一行。由于我对脚本完全不熟悉,我需要你的帮助。

以下是样本输入和预期输出。

输入:

#include <iostream>
#include <list>
#include <map>

using namespace std;

#define MIN_LEN 10
#define MAX_LEN 100

typedef list<int> IntList;

typedef 
map<int, string>
Names;

typedef Record
{
    int id;
    string name;
} MyRecord;

void putname(int a, string name)
{
    // do something...
}

输出:

#include <iostream>
#include <list>
#include <map>

using namespace std;

#define MIN_LEN 10
#define MAX_LEN 100

typedef list<int> IntList;

typedef map<int, string> Names;

typedef Record { int id;  string name; } MyRecord;

void putname(int a, string name)
{
    // do something...
}

1 个答案:

答案 0 :(得分:1)

你可以用sed做到这一点,但它有点令人费解。

/^typedef/ {    # If a line starts with 'typedef'
    /;$/! {     # If the line does not end with ';'
        :loop   # Label to branch to
        N       # Append next line to pattern space
        /;$/ {                      # If the pattern space ends with ';'
            /{[^}]*}\|^[^{]*$/ {    # If matching braces or no braces at all
                s/\n/ /g            # Replace all newlines with spaces
                s/  */ /g           # Replace multiple spaces with single spaces
                b                   # Branch to end of cycle
            }
        }
        b loop  # Branch to label
    }
}

第一种情况很简单:

typedef 
map<int, string>
Names;

这可以通过添加下一行直到找到;,然后用空格替换换行来解决。

包含更多分号的大括号使其更难以处理:如果一行以分号结尾,则只有在我们已经看到匹配的大括号或根本没有大括号(这是第一种情况)。

sedscr中存储脚本(可能没有评论,有些seds不喜欢它们),输入文件的结果如下所示:

$ sed -f sedscr infile
#include <iostream>
#include <list>
#include <map>

using namespace std;

#define MIN_LEN 10
#define MAX_LEN 100

typedef list<int> IntList;

typedef map<int, string> Names;

typedef Record { int id; string name; } MyRecord;

void putname(int a, string name)
{
    // do something...
}

这个可以写成一个单行,但它可能不应该是:

sed '/^typedef/{/;$/!{:a;N;/;$/{/{[^}]*}\|^[^{]*$/{s/\n/ /g;s/  */ /g;b}};ba}}' infile

这适用于GNU sed; BSD sed可能需要更多的分号,特别是在关闭括号之前。