【问题标题】:AWK: Converting CSV with Headers to Summary TableAWK:将带有标题的 CSV 转换为汇总表
【发布时间】:2014-03-13 00:58:36
【问题描述】:

我需要记录 100 多个 CSV 文件,这些文件的格式包括示例数据。我想做的是采用以下格式的 CSV:

Name, Phone, State
Fred, 1234567, TX
John, 2345678, NC

并将其转换为:

Field | Sample
---   | ----
Name  | Fred
Phone | 1234567
State | TX

AWK 可以做到这一点吗?从下面的示例中,您会看到我正在尝试格式化为降价表。我现在用

转置标题行
#!/usr/bin/awk -v RS='\r\n' -f
BEGIN { printf "| Field \t| Critical |\n"}
{
    printf "|---\t|---\t|\n"
    for (i=1; i<=NF; i++) {print "|", toupper($i), "| sample |"}
}
END  {}

但我现在不知道如何使用第一行数据,在表头之后显示示例数据?

【问题讨论】:

  • 你能在输出中至少给出两个样本吗?

标签: csv awk


【解决方案1】:

awk 是数据解析的正确工具。您可以尝试以下方法:

awk '
BEGIN { FS=", "; OFS=" | " }
NR==1 {
    for(tag = 1; tag <= NF; tag++) {
        hdr[tag] = sprintf ("%-7s", $tag)
    }
    next
}
{
    for(fld = 1; fld <= NF; fld++) {
        data[NR,fld] = $fld
    }
}
END {
    print "Field   | Sample\n------- | -------";
    for(rec = 2; rec <= NR; rec++) {
        for(line = 1; line <= NF; line++) {
            print hdr[line], data[rec,line]
        }
    }
}' file

输出

Field   | Sample
------- | -------
Name    | Fred
Phone   | 1234567
State   | TX
Name    | John
Phone   | 2345678
State   | NC

【讨论】:

  • 正确,非常感谢!这正是我所追求的。我喜欢互联网和所有分享他们知识的人!谢谢。
  • 由于您使用的tag值只有一个循环,您可以将for(tag = 1; tag &lt;= NF; tag++)替换为while(tag++&lt;NF)
  • @Jotne 确实,只是使用了更明确的版本。
【解决方案2】:

这是使用awk的更简单的方法
无需将所有内容存储在数组中,然后在最后打印。

awk -F", " 'NR==1{split($0,a,FS);print "Field   | Sample\n------- | -------";next} {for (i=1;i<=NF;i++) printf "%-8s| %s\n",a[i],$i}' file
Field   | Sample
------- | -------
Name    | Fred
Phone   | 1234567
State   | TX
Name    | John
Phone   | 2345678
State   | NC

它是如何工作的:

awk -F", " '                            # set field separator to ","
NR==1{                                  # if first line do:
    split($0,a,FS)                      # split first line to an array named "a" to get the labels 
    print "Field   | Sample"            # print header
    print "------- | -------"           # print separator
    next}                               # prevents nothing more run for first line
    {                                   # for all lines except first do:
    for (i=1;i<=NF;i++)                 # loop trough all element in line
        printf "%-8s| %s\n",a[i],$i     # print data for every element
    }
' file

【讨论】:

    猜你喜欢
    • 2020-12-29
    • 2015-10-26
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 2020-05-14
    • 2016-12-03
    • 2023-01-23
    • 2021-11-04
    相关资源
    最近更新 更多