You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl哈希数据打印:如何消除输出末尾的多余逗号

Perl哈希数据打印去末尾逗号解决方案

问题背景

在Perl中维护了哈希结构的统计数据,打印到控制台时每行末尾会出现多余的逗号,尝试用数组存储所有数据但不知如何按行拆分打印,需要实现无末尾逗号的规范CSV格式输出。

原脚本

#!/usr/bin/perl

use strict; use warnings;
use Data::Dumper;

my %hash = (
  '2022-08-04' => {
      'Method 1' => {
            'Count' => 50,
            'Size' => '10 MB'
      },
      'Method 2' => {
            'Count' => 40,
            'Size' => '5 MB'
      }
  },
  '2022-08-05' => {
      'Method 1' => {
            'Count' => 30,
            'Size' => '3 MB'
      },
      'Method 2' => {
            'Size' => '50 MB',
            'Count' => '100'
      }
  }
);

my @headers = ("Method 1", "Method 2");

my @headers_data;
push (@headers_data, "Date");
foreach (@headers) {
  push(@headers_data, $_." Size", $_." Count");
}
print join(",", @headers_data);
print "\n";

for my $date ( sort keys( %hash ) ) {
  my $by_method = $hash{$date};
  print "$date,";

  for my $method ( @headers ) {
    my $rec = $by_method->{$method};
    $rec->{Size} = $rec->{Size} ? $rec->{Size} : "NA";
    $rec->{Count} = $rec->{Count} ? $rec->{Count} : "NA";
    print "$rec->{Size},$rec->{Count},";
  }
  print "\n";
}

当前错误输出

Date,Method 1 Size,Method 1 Count,Method 2 Size,Method 2 Count
2022-08-04,10 MB,50,5 MB,40,
2022-08-05,3 MB,30,50 MB,100,

尝试的代码片段

...
my @data;
for my $date ( sort keys( %hash ) ) {
  my $by_method = $hash{$date};
  push (@data, $date);

  for my $method ( @headers ) {
    my $rec = $by_method->{$method};
    $rec->{Size} = $rec->{Size} ? $rec->{Size} : "NA";
    $rec->{Count} = $rec->{Count} ? $rec->{Count} : "NA";
    push (@data, $rec->{Size}, $rec->{Count});
  }
}

期望输出

Date,Method 1 Size,Method 1 Count,Method 2 Size,Method 2 Count
2022-08-04,10 MB,50,5 MB,40
2022-08-05,3 MB,30,50 MB,100

解决方案

核心思路是按行收集所有字段,再用join(",", ...)拼接输出,这样就不会产生末尾逗号。以下两种实现方式均可:

方式1:逐行收集字段(推荐)

保留原循环结构,每行单独收集所有要输出的元素,最后一次性拼接:

#!/usr/bin/perl

use strict; use warnings;

my %hash = (
  '2022-08-04' => {
      'Method 1' => { 'Count' => 50, 'Size' => '10 MB' },
      'Method 2' => { 'Count' => 40, 'Size' => '5 MB' }
  },
  '2022-08-05' => {
      'Method 1' => { 'Count' => 30, 'Size' => '3 MB' },
      'Method 2' => { 'Size' => '50 MB', 'Count' => '100' }
  }
);

my @headers = ("Method 1", "Method 2");

# 处理表头
my @headers_data = ("Date");
push @headers_data, map { "$_ Size", "$_ Count" } @headers;
print join(",", @headers_data), "\n";

# 处理每行数据
for my $date (sort keys %hash) {
    my $by_method = $hash{$date};
    my @row = ($date);
    
    for my $method (@headers) {
        my $rec = $by_method->{$method};
        push @row, 
            $rec->{Size} ? $rec->{Size} : "NA",
            $rec->{Count} ? $rec->{Count} : "NA";
    }
    
    print join(",", @row), "\n";
}

方式2:基于数组存储拆分输出

如果坚持用@data存储所有数据,可以通过计算每行的元素个数(与表头元素数一致)来拆分:

#!/usr/bin/perl

use strict; use warnings;

my %hash = (
  '2022-08-04' => {
      'Method 1' => { 'Count' => 50, 'Size' => '10 MB' },
      'Method 2' => { 'Count' => 40, 'Size' => '5 MB' }
  },
  '2022-08-05' => {
      'Method 1' => { 'Count' => 30, 'Size' => '3 MB' },
      'Method 2' => { 'Size' => '50 MB', 'Count' => '100' }
  }
);

my @headers = ("Method 1", "Method 2");

my @headers_data = ("Date");
push @headers_data, map { "$_ Size", "$_ Count" } @headers;
print join(",", @headers_data), "\n";

my @data;
for my $date (sort keys %hash) {
    my $by_method = $hash{$date};
    push @data, $date;
    
    for my $method (@headers) {
        my $rec = $by_method->{$method};
        push @data, 
            $rec->{Size} ? $rec->{Size} : "NA",
            $rec->{Count} ? $rec->{Count} : "NA";
    }
}

# 按表头列数拆分数组并输出
my $cols = scalar @headers_data;
while (@data) {
    my @row = splice @data, 0, $cols;
    print join(",", @row), "\n";
}

两种方式都能输出符合要求的结果,核心是利用join函数自动处理元素间的逗号,避免手动拼接时多打末尾逗号的问题。

内容的提问来源于stack exchange,提问作者vkk05

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 11:51:32