我想使用'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/ /'
是的-有更好的方法...
答案 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'