在bash脚本中组合多行c代码

时间:2017-05-18 06:24:38

标签: bash perl awk sed

我有C代码,开发人员以不同方式分割行:

if (x > 0) {
    syslog(
           LOG_DEBUG,
           "x > 0"
          );
} else {
    syslog(LOG_ERR,
           "error");
}

我需要的结果是:

if (x > 0) {
    syslog(LOG_DEBUG, "x > 0");
} else {
    syslog(LOG_ERR, "error");
}

空格并不重要,主要任务是在一行中调用syslog()。我能做的最好的是:

sed -i -n '/syslog(.*,$/,/.*)/{:a;N;$!ta;s/\n//;p};/syslog(.*,$/!p' file.c

但它重复了一些代码行。我做错了什么?怎么做得好?脚本语言并不重要 - sed / awk / perl ...

3 个答案:

答案 0 :(得分:2)

您应该使用C beautifier而不是尝试使用regexp来逼近C语法。例如,使用indent,因为它恰好可以在我的cygwin安装中使用:

$ cat tst.c
if (x > 0) {
    syslog(
           LOG_DEBUG,
           "x > 0"
          );
} else {
    syslog(LOG_ERR,
           "error");
}

$ indent -br tst.c

$ cat tst.c
if (x > 0) {
  syslog (LOG_DEBUG, "x > 0");
}
else {
  syslog (LOG_ERR, "error");
}

有几种C美化器(indentcbuncrustify等),可以根据需要使用各种选项来理解各种C(有时是C ++)标准和格式代码。

答案 1 :(得分:1)

使用perl

$ perl -0777 -pe 's/syslog\(\K[^)]+/$&=~s|\s+| |gr/ge' file.c
if (x > 0) {
    syslog( LOG_DEBUG, "x > 0" );
} else {
    syslog(LOG_ERR, "error");
}

答案 2 :(得分:1)

如果您遇到问题而选择使用正则表达式解决问题,最终会遇到两个问题......

package soanswer;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;

public class SOAnswer
{
  public static void main(String[] args) throws Exception
  {
    FileInputStream f = new FileInputStream(args[0]);
    BufferedReader b = new BufferedReader(new InputStreamReader(f));
    List<String> input = new LinkedList<>();
    String line = null;
    String previousline = null;
    while ((line = b.readLine()) != null)
    {
      if (line.indexOf("syslog(") >= 0)
      {
        previousline = line;
      }
      else
      {
        if (previousline == null)
          input.add(line);
        else
        {
          previousline = previousline + line;
          if (line.indexOf(");") >= 0)
          {
            input.add(previousline);
            previousline = null;
          }
        }
      }
    }

    for (String l: input)
      System.out.println(l);
  }  
}

我知道,它比正则表达式要多得多,但它的可读性要高得多。即使他不懂Java,任何编码员都能理解它。另外请记住Java非常冗长,脚本语言中的相同通常会导致更少的行。