【问题标题】:Multi-line text to CSV using AWK使用 AWK 将多行文本转换为 CSV
【发布时间】:2014-08-26 09:21:59
【问题描述】:

我有一个这样的文件:

// question: 0  name: Switch category to $cat1$/Pretest Durchführung MIT 04//05/IKT_1_PT/IKT_1_PT_2_MIT05
$CATEGORY: $cat1$/Pretest Durchführung MIT 04//05/IKT_1_PT/IKT_1_PT_2_MIT05


// question: 164887  name: PT_IKT_1_01_ FTP
::PT_IKT_1_01_ FTP::Wozu dient das FTP Protokoll?{
    ~%-100%Blah1
    ~%-100%Blah2
    =Blah3
    ~%-100%Blhah4.
}


// question: 164888  name: PT_IKT_1_02_Verteilte_Systeme
::PT_IKT_1_02_Verteilte_Systeme::Question2?{
    ~%-100%A1
    ~%-100%A2
    =A3
    ~%-100%A4
}

// question: 164893  name: PT_IKT_1_07_Rational_Unified_Process
::PT_IKT_1_07_Rational_Unified_Process::Question3?{
    ~%-50%A1
    ~%-50%A2
    ~%50%A3
    ~%50%A4
}

如何使用 AWK 创建这样的输出?

PT_IKT_1_01_ FTP;Wozu dient das FTP Protokoll?;Blah1;F;Blah2;F;Blah3;T;Blhah4.;F
PT_IKT_1_02_Verteilte_Systeme;Question2?;A1;F;A2;F;A3;T;A4;F
PT_IKT_1_07_Rational_Unified_Process;Question3?;A1;F;A2;F;A3;T;A4;T

所以 - 答案前面的文本表示错误答案,= 表示答案是正确的。但是,有些行只有一个答案是正确的,在这种情况下,没有数字表示有多少百分比的答案是正确的或假。

输入文件是https://docs.moodle.org/23/en/GIFT_format GIFT 文件格式规范的子集

【问题讨论】:

标签: csv awk gawk


【解决方案1】:

你可以这样做:

awk -v RS="" -F"\n" '$2~/^::/ {sub(/::/,"",$2);sub(/::/,";",$2);sub(/{/,"",$2);for(i=3;i<=6;i++) {n=split($i,a,"[%=]");m=m";"a[n]";"(i==5?"T":"F")};print $2 m;m=""}' file
PT_IKT_1_01_ FTP;Wozu dient das FTP Protokoll?;Blah1;F;Blah2;F;Blah3;T;Blhah4.;F
PT_IKT_1_02_Verteilte_Systeme;Question2?;A1;F;A2;F;A3;T;A4;F
PT_IKT_1_07_Rational_Unified_Process;Question3?;A1;F;A2;F;A3;T;A4;F

PS,我不知道你是怎么得到FT 的。我确实假设F;F;T;F 但你有一个F;F;T;T

更具可读性:

awk -v RS="" -F"\n" '
$2~/^::/ {
    sub(/::/,"",$2)
    sub(/::/,";",$2)
    sub(/{/,"",$2)
        for(i=3;i<=6;i++) {
            n=split($i,a,"[%=]")
            m=m";"a[n]";"(i==5?"T":"F")}
        print $2 m;m=""
    }
' file

【讨论】:

  • NF-1 可能比6 更好。此外,我认为 T/F 决定希望类似于 $i ~ /^=/ || a[2] !~ /^-/
  • @EtanReisner,我同意更改为 NF-1 可能是个好主意,因为如果 OP 想要的话,它将涵盖无限的字段。
  • @EtanReisner 不,样本是正确的。 = 是正确答案,- 表示错误答案。所以在最后一个样本中有两个正确答案。无论如何,这个建议是脆弱的。我对 (g)awk 不是很流利,但是使用例如 RS="//" 的解决方案不是更好吗?
  • @JohnDoe 根据链接的文档,领先的= 和缺少- 都是正确答案,后者是部分功劳。这也是示例输出中的 T/F 标记映射到的内容。正如所写,这不会产生这种情况。而一个空的RS 意味着在空行上分割。
猜你喜欢
  • 2021-09-22
  • 1970-01-01
  • 1970-01-01
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 2018-06-23
相关资源
最近更新 更多