【问题标题】:How can I convert my text file to a CSV?如何将我的文本文件转换为 CSV?
【发布时间】:2014-02-28 22:24:58
【问题描述】:

我有一个如下所示的文本文件:

a1: sample1
b1: sample2
c1: sample3
d1: sample4
    sample5
    sample0 

a1: sample_1
b1: sample_2
c1: sample_3
d1: sample_4
    sample_5

a1: sample_11
b1: sample_22
c1: sample_33
d1: sample_44

我需要将其转换为可以在 Excel 中访问的 CSV。最终输出应如下所示:

a1, b1, c1, d1
sample1,sample2,sample3,"sample4 sample5"
sample_1,sample_2,sample_3,"sample_4 sample_5"
sample_11,sample_22,sample_33,"sample_44 sample_55"

sample 4 和sample5 和sample0,都属于d1,即。在一排。 因此,基本上 d1 将是一个单元格,它将具有三个值,例如:

a1 b1 c1 d1 行0

sample1 sample2 sample3 sample4 row1 示例 5 第 1 行
样本0第1行

sample_1 sample_2 sample_3 sample_4 row2 sample_5 行 2

d1 现在是一个有 2 个值的单元格。

我能够解析文本文件并根据需要获取值。 无法使列 d1 以所需的方式。 我该怎么做?

需要一个 Perl 脚本来执行此操作吗? 有什么建议吗?

open(file, "f1.txt");
open(csv, ">+f2.csv");
 while($line =<file>)
   chmop;
   if($line =~/a1)
   {
   @arr1 = split(/:/,$line)
   print csv "@arr1[1],";
   }

   if($line =~/b2)
   {
   @arr2 = split(/:/,$line)
   print csv "@arr2[1],";
   }

close(file);
close(csv);

这是我到现在为止的代码。

【问题讨论】:

  • 欢迎来到 SO!请向我们展示您到目前为止所做的工作,并为您的问题添加更多详细信息!
  • 要采用 CSV 格式,a1,b1,c1,d1 之间不需要空格。您也不需要在包含空格的字段周围加上引号。
  • 在您的问题中编辑“需要 Perl 脚本”不会增加任何内容(开始时它已被标记为 perl)。 Uli Köhler 询问您编写的 Perl 代码有什么具体问题。你确实写了something,不是吗?

标签: excel perl csv


【解决方案1】:

假设您在这样的缩放器中有文件的内容:

my $input = "a1: sample1
b1: sample2
c1: sample3
d1: sample4, sample5

a1: sample_1
b1: sample_2
c1: sample_3
d1: sample_4, sample_5

a1: sample_11
b1: sample_22
c1: sample_33
d1: sample_44, sample_55";

然后你可以使用一些正则表达式(当输入与你的描述相似时):

## considering the four lines each time and no empty line as well
$input =~ s/([^\n]+)\n([^\n]+)\n([^\n]+)\n([^\n]+)/"$1","$2","$3","$4"/msg;

## removing a1: things
$input =~ s/[a-z]\d+:\s*//ig;

## removing comma around texts amid of "    ,   "
$input =~ s/(?<!"),(?!")//ig;

## finally output!
print '"a1","b1","c1","d1"'. "\n$input";

【讨论】:

    【解决方案2】:

    也许以下内容会有所帮助:

    use strict;
    use warnings;
    
    local ( $/, $" ) = ( '', ',' );
    print "a1,b1,c1,d1\n";
    
    while (<>) {
        my @fields = map { /:\s+(.+)/; $1 } split /\n/;
        print qq/@fields[ 0 .. 2 ],"$fields[3]"\n/;
    }
    

    命令行用法:perl script.pl inFile &gt; outFile

    数据集上的输出:

    a1,b1,c1,d1
    sample1,sample2,sample3,"sample4, sample5"
    sample_1,sample_2,sample_3,"sample_4, sample_5"
    sample_11,sample_22,sample_33,"sample_44, sample_55"
    

    脚本将$/ = '' 设置为段落模式,以一次读取您的文件一个块。它splits 换行符上的块,然后使用正则表达式捕获所需的字段信息。在最后一个字段周围放置双引号,并插入数组切片,由于较早的$" = ',',它在字段之间打印,

    【讨论】:

      【解决方案3】:

      这应该是这样的:

      use strict;
      use warnings;
      use Data::Dumper;
      
      open(my $TXT, "<", 'inabcd.txt') or die "Cound not open";
      open(my $CSV, ">", "outabcd.csv");
      
      my $rowcount = 0;
      my %h  = ();
      
      while(my $line = <$TXT>) {
          if($line =~ /^$/) {
              next;
          }
          chomp($line);
         my ($key, @data) = split(':',$line);
      
         if (exists $h{$key}) {
              $rowcount = $h{$key}->{'rowcount'};
              $rowcount++;
              }
      
         $h{$key}->{$rowcount} = \@data;
         $h{$key}->{'rowcount'} = $rowcount;
      }
      my @header = ();
      foreach my $el (keys %h) {
          if($el ne 'rowcount') {
              push(@header, $el);
          }
      }
      
      my $header = join(',', @header);
      
      print $CSV "$header". "\n";
      
      my $r = 0;
      while($r <= $rowcount) {
          foreach my $e (@header) {
                  print("@{$h{$e}->{$r}}" . ",");
                  print $CSV "@{$h{$e}->{$r}}" . ",";
          }
          print $CSV "\n";
          $r++;
      }
      
      close($TXT);
      close($CSV);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-26
        • 2019-04-28
        • 1970-01-01
        • 2023-03-28
        相关资源
        最近更新 更多