在bash脚本中组合多行c代码
我有C代码,其中开发人员以不同的方式拆分行:在bash脚本中组合多行c代码,bash,perl,awk,sed,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,
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…与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");
}
slurp整个文件-0777
字符串的正向查找syslog\(\K
syslog(
获取所有非[^]+
字符)
在匹配的字符串上,用单个空格替换所有空白字符$&=~s |\s+| | gr
- 使用
进行就地编辑perl-i-0777-pe
- 进一步阅读:及
- 使用
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");
}
slurp整个文件-0777
字符串的正向查找syslog\(\K
syslog(
获取所有非[^]+
字符)
在匹配的字符串上,用单个空格替换所有空白字符$&=~s |\s+| | gr
- 使用
进行就地编辑perl-i-0777-pe
- 进一步阅读:及
- 当您遇到问题并选择使用正则表达式解决时,您最终会遇到两个问题
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);
}
}
package-soanswer;
导入java.io.BufferedReader;
导入java.io.FileInputStream;
导入java.io.InputStreamReader;
导入java.util.LinkedList;
导入java.util.List;
公共类答案
{
公共静态void main(字符串[]args)引发异常
{
FileInputStream f=新的FileInputStream(args[0]);
BufferedReader b=新的BufferedReader(新的InputStreamReader(f));
列表输入=新建LinkedList();
字符串行=null;
字符串previousline=null;
而((line=b.readLine())!=null)
{
if(line.indexOf(“syslog(”)>=0)
{
前一行=前一行;
}
其他的
{
如果(上一行==null)
输入。添加(行);
其他的
{
上一行=上一行+下一行;
如果(line.indexOf(“);”>=0)
{
输入.添加(上一行);
previousline=null;
}
}
}
}
for(字符串l:输入)
系统输出打印LN(l);
}
}
我知道,它的代码要比正则表达式多得多,但可读性要高得多。任何程序员都可以理解它,即使他不懂Java。还请记住,Java非常冗长,在脚本语言中使用Java通常会导致更少的行。当您遇到问题并选择使用正则表达式解决时,您最终会遇到两个问题
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);
}
}
package-soanswer;
导入java.io.BufferedReader;
导入java.io.FileInputStream;
导入java.io.InputStreamReader;
导入java.util.LinkedList;
导入java.util.List;
公共类答案
{
公共静态void main(字符串[]args)引发异常
{
FileInputStream f=新的FileInputStream(args[0]);
BufferedReader b=新的BufferedReader(新的InputStreamReader(f));
列表输入=新建LinkedList();
字符串行=null;
字符串previousline=null;
而((line=b.readLine())!=null)
{
if(line.indexOf(“syslog(”)>=0)
{
前一行=前一行;
}
其他的
{
如果(上一行==null)
输入。添加(行);
其他的
{
上一行=上一行+下一行;
如果(line.indexOf(“);”>=0)
{
输入.添加(上一行);
previousline=null;
}
}
}
}
for(字符串l:输入)
系统输出打印LN(l);
}
}
我知道,它的代码要比正则表达式多得多,但可读性要高得多。任何程序员都可以理解它,即使他不懂Java。还请记住,Java非常冗长,在脚本语言中也是如此,通常会导致更少的行。对此,您应该使用a,而不是尝试使用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++)标准和格式代码。对此,您应该使用a,而不是尝试用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++)标准和您喜欢的格式代码。谢谢,它可以工作。它还可以使用双引号,这样就可以将“syslog”替换为变量,并在bash“for”循环中为不同的C调用执行该操作。@Andrey,您可以在perl中使用数组代替bashperl-0777-pe'BEGIN{@calls=(“syslog”,“foo”)}foreach$f(@calls){s/$f\(\K[^)]+/$&=~s |\s+| gr/ge}
尝试在错误字符串为的“糟糕(或更糟糕)情况”
时查看失败的一种方式。不要写regexp来试图理解C代码,因为你不能很好地完成这项工作,只需要使用一个工具来理解编写代码所用的特定C变体/标准-有很多这样的工具。谢谢,它可以工作。它还可以使用双引号,这样就可以将“syslog”替换为变量,并在bash“for”循环中为不同的C调用执行该操作。@Andrey,您可以在perl中使用数组代替bashperl-0777-pe'BEGIN{@calls=(“syslog”,“foo”)}foreach$f(@calls){s/$f\(\K[^)]+/$&=~s |\s+| gr/ge}
尝试在错误字符串为的“糟糕(或更糟糕)情况”
时查看失败的一种方式。不要编写regexp来试图理解C代码,因为您无法可靠地完成这项工作,只需使用下面的工具即可