我有一个包含以下格式文本的文件
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