sed:如何将记录行与分隔记录的空行连接起来

时间:2019-05-27 07:41:33

标签: sed

我想使用'sed'连接组成记录的三行,其中记录用空行分隔,记录字段用空格分隔。

这是文件中的一小段数据:

KDFW
N 32°53.83'
W 097°02.26'

TOC
N 32°48.49'
W 097°01.39'

DART
N 32°17.15'
W 096°48.66'

我需要将这样的行合并起来:

KDFW N 32°53.83' W 097°02.26'
TOC N 32°48.49' W 097°01.39'
DART N 32°17.15' W 096°48.66'

我是sed的新手,但将这条丑陋的线条拼凑在一起。

sed 'N;s/\n/ /' navlog.txt | sed 'N;s/\n/ /'

是的-有更好的方法...

5 个答案:

答案 0 :(得分:3)

我认为awk可以更好地完成这项工作:

awk -v RS="\n\n" 'gsub(/\n/," ")' file

这应该会给您预期的结果。

答案 1 :(得分:3)

如果您要查找单个sed命令而不必使用管道,则此命令应该可以正常工作!

sed 'N;N;s/\n/ /g;N;s/\n/ /;s/ $//' navlog.txt
KDFW N 32°53.83' W 097°02.26' 
TOC N 32°48.49' W 097°01.39' 
DART N 32°17.15' W 096°48.66'

Alex Harvey建议:

sed '$!N;$!N;$!N;s/\n/ /g;s/ $//' navlog.txt 
KDFW N 32°53.83' W 097°02.26' 
TOC N 32°48.49' W 097°01.39' 
DART N 32°17.15' W 096°48.66'

如果文件的末尾确实是空行,则:

$ cat navlog.txt 
KDFW
N 32°53.83'
W 097°02.26'

TOC
N 32°48.49'
W 097°01.39'

DART
N 32°17.15'
W 096°48.66'

^^^^^^^^^^^

您可以将命令简化为:

sed 'N;N;N;s/\n/ /g;s/ $//' navlog.txt
KDFW N 32°53.83' W 097°02.26' 
TOC N 32°48.49' W 097°01.39' 
DART N 32°17.15' W 096°48.66'

potong的另一个很棒的建议是

  

如果要删除空行,则最好对其进行明确说明,因为所有其他解决方案的确在该行的末尾添加了一个空格,此后需要通过(s/ $//)删除,使用起来更直接:

sed '/\S/!d;N;N;s/\n/ /g'navlog.txt
KDFW N 32°53.83' W 097°02.26' 
TOC N 32°48.49' W 097°01.39' 
DART N 32°17.15' W 096°48.66'

答案 2 :(得分:3)

您无需为此使用sed。只需使用粘贴:

▶ paste - - - - < input
KDFW    N 32°53.83'     W 097°02.26'
TOC     N 32°48.49'     W 097°01.39'
DART    N 32°17.15'     W 096°48.66'

请注意,如BSD手册中所述,用于粘贴:

  

如果为一个或多个输入文件指定了-,则使用标准输入。对于-的每个实例,一次循环读取一次标准输入。

还请注意,该输出默认情况下是制表符分隔的,您也可以使用空格分隔的输出,这似乎是您的sed所做的:

▶ paste -d' ' - - - - < input
KDFW N 32°53.83' W 097°02.26' 
TOC N 32°48.49' W 097°01.39' 
DART N 32°17.15' W 096°48.66' 

答案 3 :(得分:2)

Perl:

perl -pe 's/\n/ / if /./' navlog.txt

或者:

perl -pe 's/\n/ / if $.%4' navlog.txt

答案 4 :(得分:1)

比Kent的版本短

awk -v RS= '{$1=$1}1'
  

如果RS为空,则记录由由加上一个或多个空行组成的序列分隔,前导或尾随空白行不应导致空记录输入的开始或结尾,并且 始终是字段分隔符,无论FS的值是什么。

所以这里的技巧是自己重新定义第一个字段$1,这将使用$0(默认为空格)作为字段分隔符来重建完整记录OFS,从而合并线。

备注:如果在原始输入中放置了多个连续的空格或制表符,则它们将被替换为一个空格。可以通过定义FS来解决:

awk -F\n -v RS= '{$1=$1}1'