我正在将几个不守规矩的早期90年代DOS生成的文本文件转换为更有用的东西。我需要将一组字符附加到所述文本文件中的所有非空行中,这些行不是以空格开头,后面是两行,另一行是非空行不是以空格开头(我将把满足这些特征的所有单行文本称为“目标”行)。与此问题无关的BTW是每条目标线下方直接行的特征。
令人感兴趣的是,上述文本文件中的所有目标行都以相同的字符结尾。此外,我正在寻找的命令需要插入一个相当长的管道。
假设我有以下文件:
foo
third line foo
fifth line foo
this line starts with a space foo
this line starts with a space foo
ninth line foo
eleventh line foo
this line starts with a space foo
last line foo
我希望输出看起来像这样:
foobar
third line foobar
fifth line foo
this line starts with a space foo
this line starts with a space foo
ninth line foobar
eleventh line foo
this line starts with a space foo
last line foo
虽然我正在寻找一种sed解决方案,但也欢迎使用awk和perl。所有解决方案都必须能够在管道中使用。同样欢迎处理更一般情况的解决方案(例如,能够将所需文本附加到以各种方式结束的目标行,包括空格)。
现在,对于背景故事:
我最近几天前问了一个与主题相似的问题(见here)。如你所见,我得到了一些很好的答案。然而,事实证明,我并没有完全理解我的问题,所以我没有问到能够解决问题的正确问题。
现在,我问的是正确的问题!
基于我通过仔细检查上面链接的问题的答案而学到的东西,我拼凑了以下sed命令
sed '1N;N;/^[^[:space:]]/s/^\([^[:space:]].*\o\)\(\n\n[^[:space:]].*\)$/\1bar\2/;P;D' infile
丑陋,是的,但它适用于我的卑微目的。事实上,由于我对此问题的初衷是发布一个问题,然后自我回答相同,您可以看到下面发布的sed
构造作为答案之一(由我发布)。
我确信有更好的方法来解决这个问题,但是......任何想法,任何人?
答案 0 :(得分:0)
从你发布的预期输出看起来你想说"被跟随,两行向下,一行不是以空格开头"而不是"跟随,两行向下,一行 DOES 以空格开头"。
这会产生您显示的输出:
$ cat tst.awk
NR>2 { print p2 ((p2 ~ /^[^[:blank:]]/) && /^[^[:blank:]]/ ? "bar" : "") }
{ p2=p1; p1=$0 }
END { print p2 ORS p1 }
$ awk -f tst.awk file
foobar
third line foobar
fifth line foo
this line starts with a space foo
this line starts with a space foo
ninth line foobar
eleventh line foo
this line starts with a space foo
last line foo
它只保留一个2行缓冲区并添加" bar"在您需要的任何条件下打印到最后一行。它适用于所有POSIX awks以及支持POSIX字符类的任何其他功能(其余部分,将[[:blank:]]
更改为[ \t]
)。
答案 1 :(得分:0)
您过度分析了问题,现在您的问题显示为计算机程序,并且您的程序错误。最好使用示例和实际数据来解释需求,以便我们有希望在头脑中合理化问题
此Perl程序会改变您的算法,以使输出与您所需的输出相匹配
foobar
third line foobar
fifth line foo
this line starts with a space foo
this line starts with a space foo
ninth line foobar
eleventh line foo
this line starts with a space foo
last line foo
<%
String vlemail=request.getParameter("vlemail");
try
{
String str="jdbc:mysql://localhost:3306/licet";
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con=null;
con=DriverManager.getConnection(str,"root","");
Statement st=con.createStatement();
ResultSet rs =st.executeQuery("select Password from record where Email='"+vlemail+"'");
while(rs.next())
{
String a=rs.getString("Password");
}
out.println("Retrieved" );
}
catch(Exception e)
{
out.println(e);
out.println("Not retrieved");
}
%>
答案 2 :(得分:-1)
这个sed one-liner似乎可以解决OP中概述的具体案例:
sed '1N;N;/^[^[:space:]]/s/^\([^[:space:]].*\o\)\(\n\n[^[:space:]].*\)$/\1bar\2/;P;D' infile
感谢Benjamin W.在one of my recent questions的答案中提供的出色的澄清信息,我能够拼凑出这个解决我特定问题的单线程。如果您希望深入了解所述命令,请参阅相同内容。