使用 awk 处理文本文件以符合 CSV 平面文件格式

使用 awk 处理文本文件以符合 CSV 平面文件格式

我为我正在进行的一项实验收集了 100 多名参与者的反应时间数据。不幸的是,字段之间的分隔符不一致,但是经过 sed 的一番苦心之后,我设法解决了这个问题。

该实验被分为多个块(每个参与者 5 个),我需要的是每个块都在自己的行上输出,并用逗号分隔。

这是我的数据文件的示例:

Participant: 2456, Test: Optimism IAT. Format is stimulus ,  correct(1)/incorrect(0) ,  time(ms).  Writes 10 trials per line.
17/01/2011, 12:46:03 ,
Block 1: , Theirs   , 1        , 1921     , Myself   , 1        , 928      , Them     , 1        , 716      , Theirs   , 1        , 720      , Myself   , 1        , 533      , Me       , 1        , 596      , Themselves , 1        , 527      , Myself   , 1        , 656      , Mine     , 1        , 551      , Myself   , 1        , 624
     , Themselves , 1        , 570      , Me       , 1        , 514
     ,Block 1 Time,: 8856    ,
Block 2: , Failing  , 1        , 1835     , Happy    , 1        , 1118     , Sad      , 1        , 673      , Succeeding , 1        , 690      , Improving , 1        , 795      , Succeeding , 1        , 602      , Worse    , 1        , 586      , Succeeding , 1        , 553      , Improving , 1        , 619      , Disimproving , 1        , 659
     , Succeeding , 1        , 596      , Failing  , 1        , 539
     ,Block 2 Time,: 9265    ,
Block 3: , Succeeding , 1        , 2881     , Disimproving , 1        , 1072     , Mine     , 1        , 1120     , Me       , 1        , 627      , Happy    , 1        , 669      , Theirs   , 1        , 1539     , Worse    , 1        , 841      , Me       , 1        , 862      , Sad      , 1        , 1370     , Succeeding , 1        , 1115
    , Worse    , 1        , 855      , Theirs   , 1        , 792      , Them     , 1        , 627      , Better   , 1        , 735      , Me       , 1        , 626      , Happy    , 1        , 622      , Succeeding , 1        , 616      , Mine     , 1        , 646      , Them     , 1        , 599      , Disimproving , 1        , 607
     , Better   , 1        , 799      , Myself   , 1        , 1408     , Me       , 1        , 463      , Better   , 1        , 839      , Failing  , 1        , 602      , Mine     , 1        , 633      , Better   , 1        , 525      , Sad      , 1        , 573      , Worse    , 1        , 770      , Me       , 1        , 508
     , Theirs   , 1        , 613      , Disimproving , 1        , 649      , Improving , 1        , 701      , Theirs   , 1        , 590      , Disimproving , 1        , 716      , Better   , 1        , 714
     ,Block 3 Time,: 29924   ,
Block 4: , Them     , 1        , 1659     , Myself   , 1        , 1036     , Themselves , 1        , 595      , Me       , 1        , 509      , Myself   , 1        , 648      , Themselves , 1        , 542      , Myself   , 1        , 536      , Mine     , 1        , 537      , Theirs   , 1        , 615      , Mine     , 1        , 520
     , Me       , 1        , 596      , Mine     , 1        , 471
     ,Block 4 Time,: 8264    ,
Block 5: , Mine     , 1        , 1527     , Myself   , 1        , 1235     , Disimproving , 0        , 2001     , Theirs   , 1        , 981      , Succeeding , 1        , 1994     , Happy    , 1        , 1454     , Failing  , 1        , 1941     , Theirs   , 1        , 1151     , Failing  , 0        , 1358     , Me       , 1        , 790
     , Failing  , 1        , 717      , Mine     , 1        , 585      , Myself   , 1        , 821      , Themselves , 1        , 793      , Disimproving , 1        , 965      , Succeeding , 1        , 727      , Worse    , 1        , 961      , Theirs   , 1        , 1259     , Mine     , 1        , 578      , Better   , 1        , 1112
    , Mine     , 1        , 1207     , Happy    , 1        , 843      , Worse    , 1        , 1064     , Failing  , 1        , 699      , Happy    , 1        , 700      , Myself   , 1        , 516      , Them     , 1        , 794      , Me       , 1        , 526      , Sad      , 1        , 1118     , Improving , 1        , 826
     , Mine     , 1        , 540      , Succeeding , 1        , 952      , Myself   , 1        , 536      , Themselves , 1        , 851      , Improving , 1        , 865      , Mine     , 1        , 582
     ,Block 5 Time,: 35569  

正如您所看到的,每个块占用多行。我需要它们按以下格式占据一行

Participant Date Time   Block  Word1 Correct1 Time1.....Word36 Correct36  Time36
2456                    1      Happy   1      1200       sad    0         1500
.
.
.
1234                     5    sad       0     1100       happy   1       900

问题是块 3 和 5 有 36 个刺激,而块 1,2 和 4 有 12 个。我还需要每行中的参与者、日期时间和块时间。

这是将数据转换为您在此处看到的表单的脚本,但它并没有仅在一行上提供我所需要的每个块。

BEGIN{
    FS="\\";
    RS="#";
    OFS=",";
    ORS="\n";
}{
    for(i=1;i<=NF;i++) {printf "%-10s", $i; printf ",";} 

}

我在 Ubuntu 10.04 上使用 gawk 版本 3.1.6。

答案1

如果我理解正确,您的问题是处理输入,其中每个记录都包含多行,并且您不会检测到记录的结尾,而是检测到新记录的开头:每当行不以以下方式开头时,新记录就会开始一个逗号。

这是一些 awk 样板,您可以使用它来预处理记录的输入。

function process (record) {
    RS = " *, *"; /*gawk allows RS to be a regexp; some implementations would require setting RS="," and manually trimming spaces*/
    $0 = record; /*automatically sets $1, $2, ..., and NF*/
    record = "";
    /*your code goes here*/
}
{ if (/^ *,/) {record = record $0} else {process(record); record=$0} }
END { if (record != "") {process(record)} }'

相关内容