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

Perl脚本合并CSV特定模式间多行异常,求修正方案

问题分析与脚本修正

原脚本的核心问题

  1. 范围操作符误用:/Module Statements/ .. /6.4*/会把每一行CSV(每行均以Module Statements开头、6.*结尾)判定为独立范围,完全无法识别引号内的跨多行字段内容。
  2. 中间行重复输出:在范围中间的行执行push @collect, $_后循环打印数组,导致内容重复输出。
  3. 未处理CSV引号内换行:CSV规范中引号内的换行属于同一字段,原脚本未识别此规则,直接拆分每行处理,破坏了字段完整性。

修正后的Perl脚本

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';

my $in_quote = 0;
my @current_line;

my $file = $ARGV[0] or die "请输入文件名\n";
open(my $DATA, '<', $file) or die "无法打开文件: $!";

while (<$DATA>) {
    chomp;
    # 跟踪引号状态,判断是否处于多行字段内
    my $quote_count = s/"/"/g;
    $in_quote = !$in_quote if $quote_count % 2 != 0;

    push @current_line, $_;

    # 不在引号内时,说明当前是完整的CSV行
    unless ($in_quote) {
        my $full_line = join "\n", @current_line;
        @current_line = ();

        # 处理引号内的多行内容,按预期格式合并
        $full_line =~ s/"([^"]+)"/process_quoted($1)/ge;

        say $full_line;
    }
}

# 处理引号内的文本格式
sub process_quoted {
    my ($content) = @_;
    # 替换换行为空格,合并连续空白
    $content =~ s/\n+/ /g;
    $content =~ s/\s+/ /g;
    
    # 按预期在每3个?后添加换行,还原排版
    my @parts = split /(\?)/, $content;
    my $processed = '';
    my $count = 0;
    for my $part (@parts) {
        if ($part eq '?') {
            $count++;
            $processed .= $part . ' ';
            $processed .= "\n" if $count % 3 == 0;
        } else {
            $processed .= $part;
        }
    }
    
    # 清理末尾多余空白,保留开头的换行(如6.4.5.f的格式)
    $processed =~ s/\s+$//;
    $processed =~ s/^ /\n/ if $content =~ /^\n/;
    
    return "\"$processed\"";
}

修正逻辑说明

  1. 引号状态跟踪:通过统计每行的引号数量,判断是否处于CSV的多行字段(引号内),确保完整读取整个字段内容。
  2. 字段内容格式化:将引号内的换行替换为空格,再按每3个?添加换行,匹配预期的排版要求。
  3. 完整行输出:仅当读取完完整的CSV行(退出引号状态)时,才处理并输出内容,保证CSV结构的正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 17:06:04