3

我有一个名为 mail.txt 的文件,其中的行如下所示,我想将所有这些行放在一行中

谢谢


这是输入

q2VDWKkY010407 2221878 Sat Mar 31 19:37 <Mailer-daemon>
                     (主机映射:查找(my.local.domain):延迟)
                                             <yagyavalkbhatt@yahoo.com>
                                             <ygyalkatt@yahoo.com>
q2VDWKkY010407 2221878 Sat Mar 31 19:37 <Mailer-daemon>
                     (主机映射:查找(my.local.domain):延迟)
                                             <yagyavalkbhatt@yahoo.com>
                                             <yagyav@yahoo.com>

这是输出

q2VDWKkY010407 2221878 Sat Mar 31 19:37 <Mailer-daemon>,(host map:lookup (my.local.domain): deferred),<yagyavalkbhatt@yahoo.com>,<ygyalkatt@yahoo.com>

q2VDWKkY010407 2221878 Sat Mar 31 19:37 <Mailer-daemon>,(host map: lookup (my.local.domain): deferred), <yagyavalkbhatt@yahoo.com>,<yagyav@yahoo.com>
4

4 回答 4

2

那你为什么不做呢?

open(my $fh, "<", $input_filename);

my @lines = map { chomp; $_} <$fh>; #1

close $fh;

open(my $out, ">", $output_filename);

print $out join "", @lines; # or maybe a different separator, like ","

close $out;

#that's it

注意:如果要去掉输入行开头和结尾的多余空格,可以将 line 替换#1

my @lines = map { s/\s+$//; s/^\s+//; $_} <$fh>;
于 2012-06-06T08:32:49.487 回答
2

您似乎想在记录之间的连接行和空白行之间引入逗号分隔符。

下面的代码将带有前导空格的行视为续行。我们去除前导和尾随空格并将记录粘合在一起。

#! /usr/bin/env perl

use strict;
use warnings;

*ARGV = *DATA;  # for demo only

my $line;
while (<>) {
  s/\s+$//;

  if (s/^\s+//) {
    $line .= "," . $_;
    next;
  }
  else {
    print $line, "\n\n" if defined $line;
    $line = $_;
  }
}

print $line, "\n" if defined $line;

__DATA__
q2VDWKkY010407  2221878 Sat Mar 31 19:37 <Mailer-daemon>
                     (host map: lookup (my.local.domain): deferred)
                                             <yagyavalkbhatt@yahoo.com>
                                             <ygyalkatt@yahoo.com>
q2VDWKkY010407  2221878 Sat Mar 31 19:37 <Mailer-daemon>
                     (host map: lookup (my.local.domain): deferred)
                                             <yagyavalkbhatt@yahoo.com>
                                             <yagyav@yahoo.com>

输出:

q2VDWKkY010407 2221878 Sat Mar 31 19:37 <Mailer-daemon>,(host map:lookup (my.local.domain): deferred),<yagyavalkbhatt@yahoo.com>,<ygyalkatt@yahoo.com>

q2VDWKkY010407 2221878 Sat Mar 31 19:37 <Mailer-daemon>,(host map:lookup (my.local.domain): deferred),<yagyavalkbhatt@yahoo.com>,<yagyav@yahoo.com>

上面的代码包含它自己的输入。要在真实数据上使用它,请使用# for demo only注释和整个__DATA__部分远程处理该行。然后你可以运行它

$ 加入行邮件日志

甚至

$ join-lines mail-log1 mail-log2 mail-log3

要将标准输出重定向到文件oneline.log,请将其运行为

$ join-lines mail-log >oneline.log
于 2012-06-06T11:18:06.430 回答
2

如果假设以空格开头的行是续行是安全的,则可以通过在全局字符串变量中累积每个复合记录来非常简单地做到这一点。

该程序执行所需的操作。该s/^\s+//语句既删除了前导空格,又确定了该行是否为续行。

use strict;
use warnings;

my $line = '';

while (<DATA>) {
  s/\s+\z//;
  if (s/^\s+//) {
    $line .= ','.$_;
  }
  else {
    print $line, "\n" if $line;
    $line = $_;
  }
}
print $line, "\n";

__DATA__
q2VDWKkY010407  2221878 Sat Mar 31 19:37 <Mailer-daemon>
                     (host map: lookup (my.local.domain): deferred)
                                             <yagyavalkbhatt@yahoo.com>
                                             <ygyalkatt@yahoo.com>
q2VDWKkY010407  2221878 Sat Mar 31 19:37 <Mailer-daemon>
                     (host map: lookup (my.local.domain): deferred)
                                             <yagyavalkbhatt@yahoo.com>
                                             <yagyav@yahoo.com>

输出

q2VDWKkY010407  2221878 Sat Mar 31 19:37 <Mailer-daemon>,(host map: lookup (my.local.domain): deferred),<yagyavalkbhatt@yahoo.com>,<ygyalkatt@yahoo.com>
q2VDWKkY010407  2221878 Sat Mar 31 19:37 <Mailer-daemon>,(host map: lookup (my.local.domain): deferred),<yagyavalkbhatt@yahoo.com>,<yagyav@yahoo.com>
于 2012-06-06T13:47:41.170 回答
-1

我想出了这个:

#!usr/bin/perl
my $line;
my $i = 0;
open (FILE1, "<input.txt") or die "Can't find file";       
open (FILE2, ">output.txt") or die $!;

while($line = <FILE1>){

    if ($line =~ /<Mailer-daemon>/) 
    {
        #If it contains <Mailer-daemon> it retains its normal formatting./\

        print FILE2 substr($line, 0 , $line.length()-1); #chops off newline character
        $i++;
    }
    else
    {
        $line =~ s/\s//g; #this regex kills all whitespace...not sutiable for mailer daemon lines.
        print FILE2 $line;
        $i++;
    }

    if ($i == 4)
    {
        #Every 4th line you want two newline characters as per sample output
         print FILE2 "\n\n";
         $i = 0;
    }
    else
    {
        #comma seperator between non fourth-line parts
         print FILE2 ", "
    }
}

close FILE1;
close FILE2; 

这对于类似于您提供的输入和输出非常具体。如果格式稍有改变,我就不会运行它。

于 2012-06-06T18:01:58.487 回答