首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >均衡csv数据中的列数

均衡csv数据中的列数
EN

Stack Overflow用户
提问于 2015-03-04 16:00:26
回答 1查看 83关注 0票数 0

我正在解析从PDF文件转换为csv的一些联系数据,这导致了基于缺失条目的每一行的不同列计数。

是否有一种方法可以使用sed、awk、cut等来纠正这种情况:确保一些易于模式匹配的列( fx )确保在可用时电子邮件地址位于相同的列中,而在电子邮件不可用时,其他列(如“终身成员”或“来宾”)也在同一列中?

第一列是个人/公司的名称,其余的是任意的。关键是提取联系人信息(如电子邮件、电话号码等),并在可用时将其放在相同的列中。我的想法是检查电子邮件是否在第6栏中,如果没有,则在它之前添加一些空列等等。

示例数据:

代码语言:javascript
复制
Steve Smith;9828;1;+1234 567 2345;Guest;steve@example.org;1;1 12th st;48572 Nowhere
Steve Jobs;+1234 567 2345;noreply@example.org;1;48572 Nowhere
John Smith;9828;1;+1234 567 2345;Lifetime member;1;1 23rd st;48572 Nowhere
Peter Blavounius;2312;peter@blavounius.com

想要输出:

代码语言:javascript
复制
Steve Smith;9828;1;+1234 567 2345;Guest;steve@example.org;1;1 12th st;48572 Nowhere
Steve Jobs;+1234 567 2345;;;;noreply@example.org;1;;48572 Nowhere
John Smith;9828;1;+1234 567 2345;Lifetime member;1;1 23rd st;48572 Nowhere
Peter Blavounius;2312;;;;peter@blavounius.com
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-04 16:28:55

这将使您开始工作,但它还没有完成,您仍然需要标识其他字段,到目前为止,我所做的只是确定了几个字段,以向您展示该方法:

代码语言:javascript
复制
$ cat tst.awk
BEGIN {
    FS=OFS=";"
    ARGV[ARGC] = ARGV[ARGC-1]
    ARGC++
}

{
    name = tel = email = digs4 = ""
    for (i=1;i<=NF;i++) {
        if (i == 1) {
            name=$i; $i=""; nameFld = 1
        }
        else if ($i ~ /^\+/) {
            tel=$i; $i=""; telFld = (i > telFld ? i : telFld)
        }
        else if ($i ~ /@/) {
            email=$i; $i=""; emailFld = (i > emailFld ? i : emailFld)
        }
        else if ($i ~ /^[0-9]{4}$/) {
            digs4=$i; $i=""; digs4Fld = (i > digs4Fld ? i : digs4Fld)
        }
    }
    maxFlds = (NF > maxFlds ? NF : maxFlds)
}

NR>FNR {
    for (i=1;i<=maxFlds;i++) {
        if (i == nameFld)       { $i = name }
        else if (i == telFld)   { $i = tel }
        else if (i == emailFld) { $i = email }
        else if (i == digs4Fld) { $i = digs4 }
        else { $i = $i } # make sure null fields are present
    }
    print
}

代码语言:javascript
复制
$ awk -f tst.awk file
Steve Smith;9828;1;+1234 567 2345;Guest;steve@example.org;1;1 12th st;48572 Nowhere
Steve Jobs;;;+1234 567 2345;48572 Nowhere;noreply@example.org;;;
John Smith;9828;1;+1234 567 2345;Lifetime member;;1 23rd st;48572 Nowhere;
Peter Blavounius;2312;;;;peter@blavounius.com;;;

它对输入文件进行了2次传递--第一个用于识别与每个regexp匹配的最大字段号,因为您希望每个匹配该regexp的字段出现在输出中,第二个字段标识字段,清除它们在记录中的位置,然后将每个字段放在正确的位置。

您可以通过将字段的上下文与上面这样的regexp匹配,或者通过其在行中的固定位置(例如人名总是在字段1中)或通过字段与其他字段的相对位置(例如,在电子邮件地址之前或在第三个字段号之前/之后出现的单个数字或.)来确定字段的含义。

希望这有意义。添加一些printfs,并玩它一点,并提出问题,如果你在此之后感到困惑。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28859036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档