根据下一行的格式删除换行符

时间:2013-07-22 16:07:25

标签: sed

我有一个这种格式的特殊文件:

title1
_1 texthere
title2
_2 texthere

我希望所有以“_”开头的换行符作为第二列放在

之前的行

我尝试使用sed使用此命令执行此操作:

sed 's/_\n/ /g' filename

但它没有给我我想要做的事情(基本上什么都不做)

有人能指出我这样做的正确方法吗?

由于

4 个答案:

答案 0 :(得分:3)

尝试以下解决方案:

中,循环完成后会创建一个标签(:a),而不匹配最后一行($!)会追加下一个(N)并返回标签a

:a
$! {
  N
  b a
}

在此之后,我们将整个文件放入内存中,因此对换行符前面的每个_进行全局替换:

s/\n_/ _/g
p

一起是:

sed -ne ':a ; $! { N ; ba }; s/\n_/ _/g ; p' infile

产量:

title1 _1 texthere
title2 _2 texthere

答案 1 :(得分:3)

如果你的整个文件就像你的样本(线对),那么最简单的答案就是

paste - - < file

否则

awk '
    NR > 1 &&  /^_/ {printf "%s", OFS} 
    NR > 1 && !/^_/ {print ""} 
    {printf "%s", $0} 
    END {print ""}
' file 

答案 2 :(得分:2)

这可能适合你(GNU sed):

sed ':a;N;s/\n_/ /;ta;P;D' file

这可以避免将文件篡改到内存中。

或:

sed -e ':a' -e 'N' -e 's/\n_/ /' -e 'ta' -e 'P' -e 'D' file

答案 3 :(得分:1)

Perl方法:

perl -00pe 's/\n_/ /g' file 

这里,-00导致perl以段落模式读取文件,其中&#34;行&#34;由两个连续的换行符定义。在您的示例中,它将整个文件读入内存,因此,使用空格对\n_进行简单的全局替换将起作用。

但对于非常大的文件来说,这不是很有效。如果您的数据太大而无法容纳在内存中,请使用:

perl -ne 'chomp; 
          s/^_// ? print "$l " : print "$l\n" if $. > 1; 
          $l=$_; 
          END{print "$l\n"}' file 

此处,逐行读取文件(-n),并从所有行(chomp)中删除尾随换行符。在每次迭代结束时,当前行保存为$l$l=$_)。在每一行中,如果替换成功并且从行的开头_移除了s/^_//,那么前一行将打印一个空格代替换行符{{1} }。如果替换失败,则使用换行符打印上一行。 print "$l "块只打印文件的最后一行。