我的文本文件如下所示:
This is one
sentence that is broken.
However this is a good one.
And this
one is
somehow, broken into
many.
我想删除后面跟着以小写字母开头的行的任何行的尾随换行符。
所以这应该是:
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.
我怎样才能做到这一点?
编辑:这里有一些非常好的答案,但我选择接受第一个有效的答案和是最早的。非常感谢大家!
答案1
和awk
:
awk -v ORS= '{print (NR == 1 ? "" : /^[[:lower:]]/ ? " " : RS) $0}
END {if (NR) print RS}'
也就是说,不要将记录分隔符附加到每行(ORS 为空)。但前置当前行之前的记录分隔符(如果不在第一行并且当前行不以小写字母开头)。否则,请在前面添加一个空格字符,第一行除外。
答案2
尝试
awk '$NF !~ /\.$/ { printf "%s ",$0 ; next ; } {print;}' file
在哪里
$NF !~ /\.$/
匹配最后一个元素不以点结尾的行,{ printf "%s ",$0
打印此行并带有尾随空格,并且不换行,next ; }
获取下一行,{print;}
并打印它。
我确信会有一个sed
选择。
注意:这适用于以点结尾的行,但是以大写字母开头的句子中的条件不会被合并。请参阅 Stéphane Chazelas 的回答。
答案3
在 Perl 中:
#!/usr/bin/perl -w
use strict;
my $input = join("", <>);
$input =~ s/\n([a-z])/ $1/g;
print $input;
从技术上讲,您希望将“换行符后跟小写字母”替换为“空格和小写字母”,这就是上面 perl 脚本的核心功能:
- 读入字符串的输入
input
。 - 将变量更新
input
为搜索和替换操作的结果。 - 打印新值。
答案4
使用sed
和fmt
:
$ sed -e '1n; s/^[[:upper:]]/\n&/' input.txt | fmt
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.
sed 脚本在以大写字母开头的每一行之前插入换行符(输入的第一行除外)。 sed
然后将 的输出通过管道输入fmt
以重新格式化结果段落。
par
如果您已安装,也可以使用。它是另一个段落重新格式化程序,但比 更强大fmt
,具有更多功能和选项。
请注意,每个段落之间会有一个空行。段落应该彼此之间至少用一个空行分隔。如果没有空行,您的整个输入示例将被重新格式化为单个多句子段落,例如:
$ fmt input.txt
This is one sentence that is broken. However this is a good one.
And this one is somehow, broken into many.
如果您需要在重新格式化后删除空白行,只需sed
再次通过管道将其通过 - 但这将删除所有空白行,包括原始输入中可能存在的任何空白行。例如
$ sed -e '1n; s/^[[:upper:]]/\n&/' input.txt | fmt | sed -e '/^$/d'
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.