把Perl中文件的多行内容合并成一个文件

3

我有一个名为mail.txt的文件,其中打印的行如下,我想把所有这些行放到一个单一的行中,就像这样

谢谢


这是输入

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>

duplicate - tuxuday
4个回答

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>

谢谢Borodin,感谢您的回答,但我需要知道如何将其输出到文件中。 - Yagyavalk Bhatt

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

注意:如果您想要去除输入行开头和结尾的额外空格,可以将第一行 #1 替换为以下内容。
my @lines = map { s/\s+$//; s/^\s+//; $_} <$fh>;

感谢jpalecek,我尝试了您提交的代码,但它没有起作用,它给我的结果与之前相同。 - Yagyavalk Bhatt
@yagyavalkbhatt:是的,我总是忘记去掉行终止符。现在应该可以工作了。 - jpalecek
谢谢jpaleck。 非常感谢,它完美地运行了,但我想要的唯一一件事是输出应该像帖子中所述的那样。目前我得到的是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我想在laas电子邮件ID的>末尾加上\n。 - Yagyavalk Bhatt
3
这个解决方案仅仅是将文件中的记录连接成一行文本。这与问题中所需的输出完全不同。 - Borodin
@Borodin:引用问题:“我想把所有这些行放到一行中”。如果OP想要其他东西,他应该描述它。 - jpalecek

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>,(主机映射: 查找(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>

以上代码包含了自己的输入。要在实际数据上使用它,请删除带有# for demo only注释的行和整个__DATA__部分。然后,您可以像下面这样运行它:

$ join-lines mail-log

甚至可以像下面这样将标准输出重定向到文件oneline.log中:

$ join-lines mail-log >oneline.log

谢谢Greg的回答,但是我需要知道如何将它的输出放入一个文件中。 - Yagyavalk Bhatt
@YagyavalkBhatt 我建议使用重定向,因为这是最灵活的方法。请参见更新的答案。 - Greg Bacon

-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; 

这非常特定于输入和输出,类似于您提供的内容。如果格式稍有变化,我不会运行它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接