sed替换包括换行符

5
我想修改一个文本文件,使得任何以“Length:”开头的行都被附加到前面的一行。
我知道sed '/\nLength:/ Length:/'不起作用,因为sed是基于行的。
在谷歌上搜索“如何在sed中匹配换行符”确实找到了一种复杂的sed方法,可以将模式与下一行连接起来,但我无法弄清楚如何适应它。
希望能得到帮助。
3个回答

2
awk 中,您可以使用以下内容:
awk '/^/&&!/^Length/{printf "\n"}{printf "%s",$0}' infile

只有在匹配到行首^时才会打印出\n。例外情况:在那个开头找到了Length


2
我个人更喜欢将 printf "\n" 改为 print ""(但这只是一种风格问题)。然而,你应该使用 printf 的格式说明符,比如 printf "%s", $0,以避免行中的字符被解释。 - Tom Fenech
我同意,格式化程序应该更清晰 @TomFenech - Juan Diego Godoy Robles
另一个小问题 - printf 不是一个函数,所以你不需要括号(实际上有些人更喜欢避免使用它们)。除此之外,看起来很好! - Tom Fenech
谢谢。很完美。 - Dave Rove

2
如果文件不太大,您可以使用Perl命令行进入 slurp 模式 (在处理之前加载所有文件内容) :
perl -0777 -pe 's/\R(?=Length:)//g' file

-0777开启 slurp 模式

模式:

\R 匹配任何类型的换行符

(?=...) 正向预查

如果没有以 Length: 开头的连续行,您可以使用以下 sed 命令:

sed -n ':a;/\nLength:/!{$p;N;ba;}; s/\n\(Length:\)/$1/;p;' file

细节:

:a;                  # define the label "a"
/\nLength:/! {       # if "\nLength:" doesn't match then:
    $p;              # if last line, print
    N;               # append the next line to the pattern space
    ba;              # go to label "a"
};
s/\n\(Length:\)/$1/; # perform the replacement
p;                   # print

使用记录分隔符,awk 还有另一种方法:
awk 'BEGIN{RS="\nLength:";ORS="Length:"}1' file | head -n -1

感谢提供示例和描述。 - Dave Rove

0
这可能适用于您(GNU sed):
sed 'N;/\nLength:/s/\n/ /;P;D' file

这将下一行附加到模式空间中的当前行,如果附加的行以所需字符串开头,则将换行符替换为空格(如果您不想要空格,只需将换行符替换为无)。然后打印并删除第一行,并重复该过程(第二行现在是第一行,除非满足条件,在这种情况下会自动读取一行,然后第一个命令附加下一个行)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接