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

sed:如何将记录的行与分隔记录的空行连接起来,sed,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' 我是se

我想使用“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/ /'

是的-有一个更好的方法…

我认为awk更适合这份工作:

awk -v RS="\n\n" 'gsub(/\n/," ")' file
这将为您提供预期的结果。

Perl:

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


如果您正在寻找单个
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'
或建议:

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'
另一个很好的建议是

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


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

▶ 粘贴-<输入
KDFW北纬32°53.83'西097°02.26'
TOC N 32°48.49'宽097°01.39'
省道N 32°17.15'宽096°48.66'
请注意,如BSD粘贴手册中所述:

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

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

▶ 粘贴-d''--<输入
KDFW北纬32°53.83'西097°02.26'
TOC N 32°48.49'宽097°01.39'
省道N 32°17.15'宽096°48.66'

比Kent版本略短

awk -v RS= '{$1=$1}1'
如果
RS
为空,则记录由一个加上一个或多个空行组成的序列分隔
,前导或尾随空行不得在输入的开始或结束处产生空记录,a应始终是字段分隔符,无论
FS
的值是多少。

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

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

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

RS='\n\n'
是默认值,如果
RS=
@Thor有点迂腐,如果
RS
为空,则记录由一个加上一个或多个空行的序列分隔,前导或尾随空行不应导致输入开始或结束时的空记录,并且a应始终是字段分隔符,无论
FS
的值是什么。这实际上可能会失败,如果记录只有一行,只要
gsub
将返回
0
@kvantour,如果在这种情况下,
'1+gsub(…)
可能会修复它?@Kent是的,但我认为说
'{gsub(/\n/,“)}1'
,甚至更干净
'{gsub(/n/,of)}1'
看到其他解决方案总是很高兴!另外,要处理任意数量的行,请使用
“$!N、 美元!N、 美元!Ns/\n//g'
。所有这些解决方案都会在行尾追加一个空格(如果最后一行不是空的,则最后一行除外)。如果要删除空行,最好是显式地使用
sed'/\S/!DNNs/\n//g'文件
awk -v RS= '{$1=$1}1'
awk -F\n -v RS= '{$1=$1}1'