【问题标题】:How to write each row of a text file into CSV如何将文本文件的每一行写入 CSV
【发布时间】:2019-06-04 17:20:12
【问题描述】:

我有一个文本文件中的 netflow 信息报告,我想将它们导出为 csv 格式,我该如何在 Perl 中做到这一点?我是 Perl 新手,刚开始学习它。

这是文本文件:

Duration    Flags    
10.10.10.1      10.10.11.11    51251    445      2019-03-05 11:59:29.008   29.156     ......
10.10.10.2      10.10.11.22    51234    123      2019-03-05 11:40:29.008   30.156     .A..SF

我想将其导出为ex​​cel格式,如下所示。

10.10.10.1,10.10.11.11,51251,445,2019-03-05 11:59:29.008,29.156,......  
10.10.10.2,10.10.11.22,51234,123,2019-03-05 11:59:29.008,30.156,.A..SF  

我已经尝试做如下,

use strict;
use warnings;

open my $fh, '<', 'file.txt';
open my $fo, '>', 'file.csv';
while (<$fh>) {
   next if ($. == 1);
   s/\b \b/,/g;
   my $text = (join ',', (split /\s+/, $_))."\n";
   print $fo $text;
}

但结果是每一行开始都会多加一个',',如下,

,10.10.10.1,10.10.11.11,51251,445,2019-03-05 11:59:29.008,29.156,......  
,10.10.10.2,10.10.11.22,51234,123,2019-03-05 11:59:29.008,30.156,.A..SF  

这就是我想要的,我的代码有什么问题?

10.10.10.1,10.10.11.11,51251,445,2019-03-05 11:59:29.008,29.156,......  
10.10.10.2,10.10.11.22,51234,123,2019-03-05 11:59:29.008,30.156,.A..SF  

无论如何要这样做? 谢谢。

【问题讨论】:

  • 你试过什么?你有什么问题?请向我们展示您的代码。
  • @georgetovrea 我已经尝试了您编辑中的代码,但我的 csv 中没有第一个逗号。
  • 无论如何,如果您跳过第一行 s/\b \b/,/g; 是不需要的。您的输入可以在列之前有空格吗?
  • @sergiotarxz 我已经推荐了“ s/\b \b/,/g;”这一行,但仍然得到相同的结果。每行开头都是','
  • 加s/^\s+//;在拆分/加入之前。 (你得到的结果正是我在每一行输入前加空格时得到的结果)

标签: perl csv


【解决方案1】:

这个问题有几个步骤。我将不只是将答案交给您,而是会告诉您完成这些步骤,并为您指出一些功能的文档,这些功能将在每个阶段为您提供帮助。

  1. 您需要打开两个文件句柄 - 一个用于读取数据,一个用于写入(转换后的)数据。 open() 函数用于打开文件并将该文件附加到文件句柄,您可以使用该文件句柄从文件中读取数据。
  2. 然后您需要从输入文件句柄中读取数据。为此,您可以使用 file input operator (&lt; ... &gt;)。
  3. 然后您需要将输入行拆分为各个字段。 Perl 有一个巧妙地命名为 split() 的函数来执行此操作。
  4. 然后,您需要根据拆分的输入数据构建 CSV 记录。您可能会考虑为此使用Text::CSV 模块,但在这种(简单)情况下,您可以只使用join()
  5. 您需要将 CSV 记录写入输出文件。你可以使用print() 来做到这一点。
  6. 最后,您需要关闭两个文件句柄 - 您可以使用 close()

我故意没有提及您问题的一个有趣的角落。每个人都需要一个大问题来解决问题,对吗? :-)

尝试根据这些信息写一些东西,如果您有更多问题,请随时在这里提问。

【讨论】:

    【解决方案2】:

    这样的东西可以用吗?

    use strict;
    use warnings;
    
    open my $fh, '<', 'text.txt';
    open my $fo, '>', 'text.csv';
    while (<$fh>) {
        s/^\s+//;
        s/\b \b/_/g;
        my $text = (join ',', (split /\s+/, $_))."\n";
        print $fo $text;
    }
    

    【讨论】:

    • 我认为你需要对标题行更聪明一点。
    • @DaveCross 我已经更新了回复,感谢您指出错误。
    • 我想我会选择s/\b \b/_/g
    • @DaveCross 我总是忘记单词边界 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多