2

我有一个如下所示的文本文件。它有一些我想删除的额外换行符。

LINE1: @Line1Col1 @Line1Col2

LINE2: @Line1Col3 @Line1Col4 @ Line1Col5@

LINE3: @Line2Col1 @Line2Col2 @Line2Col3

LINE4: @Line2Col4@

LINE5: Line2Col5 @

我想删除换行符,使其看起来像这样:

@Line1Col1 @Line1Col2 @Line1Col3 @Line1Col4 @Line1Col5@

@Line2Col1 @Line2Col2 @Line2Col3 @Line2Col4@ Line2Col5@

如果一行以@定界符开始并以@定界符结束,则该行被定义为完整。请注意,分隔符 @ 已存在于文件中。例如,追加 LINE1 和 LINE2 使该行完整。类似地,附加 LINE3、LINE4 和 LINE5 会形成另一个完整的行(其中,在每一行上,数据 LineXcolX 用于说明目的)。因此,我需要删除 LINE1 中存在的换行符并保留 LINE2 中的换行符。同样,我需要删除 LINE3 和 LINE4 中的换行符并保留 LINE5 中的换行符。中间可以有多个空格;因此,空格不能用于解决方案。

重新编辑[添加了实际文件的一部分]

我能想到的一个逻辑是,仅在前一行以“@”结尾且当前行以“@”开头的条件下保留新行。但是,我不确定如何在 shell 中实现这一点,或者是否可能有更好的逻辑。

@ 258908159@ 258908159@Subwork=E,Mment=SS09 @ 4@2012 年 6 月 5 日 23:24:41 @2012 年 6 月 5 日 23:24:00 @ 2@ * "DUMMYI"U 120605 DUMMY DATA @Jun 5 2012 23:26:00 @ 403@ 21@PRCAIE @ 10780093@ -2@ @ -1@ -2@ 1@ 35@ 1@@ -1@ NULL@ -1@ 154@ 1@ 40958044@ 1@ 1@ 3@ 0@ -2@ 1@ @ 258908158@ 258908158@Subwork=E,Mment=SS09 @ 4@Jun 5 2012 23:24: 41 @2012 年 6 月 5 日 23:24:00 @ 2@ 3TEST300@2@3TEST300@2@3TEST3Mment=SS09 @ 4@Jun 5 2012 23:24:41 @Jun 5 2012 23:24:00 @ 2@ 3TEST3Mment=SS09 @ 4@Jun 5 2012 23:24:41 @Jun 5 2012 23:24:00 @ 2@ 3TEST3
结束@2012 年 6 月 5 日 23:26:00@402@21@@10780093@-2@@-1@-2@1@35@1@@ -1@ NULL@ -1@ 154@ 1@ 40958044@ 1@ 1@ 3@ 0@ -2@ 0@

#####New Line is required 这里必须删除所有其他新行

@ 258908158@ 258908158@Subwork=E,Mment=SS09 @ 4@2012 年 6 月 5 日 23:24:41 @2012 年 6 月 5 日 23:24:00 @ 2@ * “DUMMYI”U 120605 DUMMY @Jun 5 2012 23:26:00 @ 402@ 21@PRCAIE @ 10780093@ -2@ @ -1@ -2@ 1@ 35@ 1@@ -1@ NULL@ -1@ 154@ 1@ 40958044@ 1@ 1@ 3@ 0@ -2@ 1@ @ 258908157@ 258908157@Subwork=E,Mment=SS09 @ 4@Jun 5 2012 23:24: 41 @2012 年 6 月 5 日 23:24:00 @ 2@ 3TEST300@2@3TEST300@2@3TEST3Mment=SS09 @ 4@Jun 5 2012 23:24:41 @Jun 5 2012 23:24:00 @ 2@ 3TEST3Mment=SS09 @ 4@Jun 5 2012 23:24:41 @Jun 5 2012 23:24:00 @ 2@ 3TEST3
结束@2012 年 6 月 5 日 23:26:00@401@21@@10780093@-2@@-1@-2@1@35@1@@ -1@ NULL@ -1@ 154@ 1@ 40958044@ 1@ 1@ 3@ 0@ -2@ 0@

谢谢。

4

3 回答 3

1

我的理解是我们在进行过程中连接和存储行。如果当前行以“@”开头并且存储的串联批次以“@”结尾,那么我们处于行边界。然后我们打印存储的批次并重新开始。

awk '/^@/ && l~/@$/ { print l; l=$0; next } { l=l $0} END { print l }'
于 2012-06-08T10:18:20.173 回答
0

这可能对您有用:

sed ':a;$bb;N;/@ *\n *@/!{y/\n/ /;ba};:b;P;D' file

解释:

删除除被@'s 包围的所有换行符:

  • 为循环制作一个标签::a
  • 如果最后一行换行到第二个标签b$bb
  • 将下一行追加到模式空间。N
  • 寻找被@标志包围的换行符。/@ *\n *@/
  • 如果没有这样的模式,则将换行符转换为空格并循环到 label a!{y/\n/ /;ba}
  • 找到模式(所有换行符都转换完毕)或文件结束条件。打印到换行符。:b;P
  • 删除上面打印的行并开始新的循环(不要阅读下一行)。D

一个更神秘的解决方案:

 sed '$!{N;/@ *\n *@/!{s/\(.*\)\n/\n\1/;D}};P;D' file
于 2012-06-08T11:32:56.983 回答
0

这个简单的 Perl 程序应该做你想做的事。

它的工作原理是连接输入文件中的行,并在累积的字符串包含一对@符号(可能由空格分隔)时拆分它。

请注意,它希望输入文件作为命令行上的参数,并将修改后的数据发送到 STDOUT。

use strict;
use warnings;

my $line;

while (<>) {
  chomp;
  $line .= $_;
  while ($line =~ s/^(.+?\@)\s*(?=\@)//) {
    print $1, "\n";
  }
}

print $line, "\n";

输出(使用您的示例输入数据)

@Line1Col1 @Line1Col2@Line1Col3 @Line1Col4 @ Line1Col5@
@Line2Col1 @Line2Col2 @Line2Col3@Line2Col4@Line2Col5 @

更新

从您的实际文件数据来看,好像@记录中间可以有两个 s,因此上述方法不起作用。

但看起来你正在处理@- 分隔的数据,分析它告诉我每条记录有 25 个字段,这意味着 26 个@字符。

这个替代程序累积数据直到它包含 26 个或更多@字符,然后输出它。它似乎适用于您发布的实际数据。

use strict;
use warnings;

my $line;

while (<>) {
  chomp;
  $line .= $_;
  if ($line =~ tr/\@// >= 26) {
    print ">>", $line, "\n";
    undef $line;
  }
}

print $line, "\n" if $line;
于 2012-06-08T12:47:59.320 回答