我有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 ...
答案 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美化器(indent
,cb
,uncrustify
等),可以根据需要使用各种选项来理解各种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");
}
-0777
啜饮整个文件syslog\(\K
的syslog(
正面观察
[^)]+
获取所有非)
个字符
$&=~s|\s+| |gr
,用单个空格替换所有空白字符perl -i -0777 -pe
进行内部编辑答案 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非常冗长,脚本语言中的相同通常会导致更少的行。