使用 tr 格式化文本时出现问题

使用 tr 格式化文本时出现问题

我有一个包含以下格式文本的文件

line 1,
line 2,
< Blank line >
line 3,
line 4,
< Blank line >
line 5,
line 4,
< Blank line >

我需要将其设置为以下格式:

line 1,line 2,
< Blank line >
line 3,line 4,
< Blank line >
line 5,line 4,
< Blank line >

所以我正在尝试:

tr -d '\n' < myfile.txt > myfile_res.txt

但随后我将所有内容串联起来:

line 1,line 2,line 3,line 4,line 5,line 4

我需要的是仅从包含字符的行中删除 '\n' 并保留空白行,我相信它会起作用。

知道如何编码吗?

答案1

tr一次只查看一个字符,因此当您需要检查上下文时它实际上不起作用。

由于各部分由空行分隔,因此 的段落模式awk非常适合:

awk -vRS= '{gsub(/\n/, ""); print $0 "\n"}' myfile.txt

设置RS空加载由空行分隔的“记录”,对于每个记录,我们再次删除换行符,然后使用额外的换行符打印记录。

在 Perl 中也是类似的,不过这里有两个额外的换行符,因为 Perl 会像加载任何其他字符一样加载最后的换行符:

perl -00ne 's/\n//g; print "$_\n\n"' myfile.txt

这两者都会将多个空白行视为一个空白行。


我们可以使用 sed 来完成此操作,但如果我们需要支持两行以上的块,那么它比我最初的尝试要复杂一些。

sed -n 'H; $bL; /./d; :L; x; s/\n//g; s/$/\n/; p;' myfile.txt

将当前行追加到保持缓冲区 ( H),然后检查这是否是最后一行 ( $),在这种情况下分支到 L ( bL)。如果没有,请检查是否有字符(/./),如果有,则删除(d)行并返回开始。

否则(该行为空),则进入L,我们交换 ( x) 保留缓冲区和当前行(模式空间),删除换行符 ( s/\n//g),在末尾添加另一个换行符 ( s/$/\n/) 并隐式打印模式空间,现在包含自上一个空白行以来我们收集的行。在这里,额外的空行将产生更多的额外空行。

答案2

您可以使用这个 sed 命令

sed '/,/{N;s/\n//;s/$//;}' myfile.txt

相关内容