【问题标题】:awk command to separate records and save as csvawk 命令分隔记录并保存为 csv
【发布时间】:2012-06-15 09:58:00
【问题描述】:

您好,我实际上试图管理一个 awk 脚本,该脚本会处理具有如下内容的文本文件

    . [135]Edwards Engineering Pty Ltd
       Quality Structural Steel. Specialising In Fabrication And Steel
       Stairs
       21- 23 Ada Ave, Brookvale NSW 2100
       ph: (02) 9938 5320

 . [269]Diavolo Steel Fabrication
       5 Humeside Drv, Campbellfield VIC 3061
       ph: (03) 9357 7947


       . [40]WH Williams Pty Ltd
       Your Partner For High Quality Custom-Made Metal Products
       Short lead times & unbeatable quality. Make us the first choice for
       your entire sheetmetal laser cutting,bending,welding & more.
       61- 77 Egerton St, Silverwater NSW 2128
       ph: (02) 9647 1277
            [41]www.whwilliams.com.au

等等..实际上是一个巨大的文件.. 我设法编写的脚本是

awk '$2 ~ /\. \[/{$1=x; print}' RS=\*  FS='\n' OFS='|' Myfile > excel.csv

此命令将我的文本文件转换为带有记录分隔的 csv 文件。 但正如您在上面看到的,上述示例中的地址长度是不同的,我得到一个格式不规则的 csv 文件..

所以我现在要做的是更改命令以将 1.公司名称在一个单元格中, 2.描述部分,如果存在于一个单元格中,如果不存在,则单元格留空, 3. 一个单元格中的地址部分, 4. 一个单元格的电话号码 5.一个单元格中的网站.. 如果任何特定组件不存在,则该单元格应留空..

我是 linux 新手,正在尝试处理一些东西,而且对 shell 和 awk 也很陌生.. 如果有可能,任何人都可以帮助我...

【问题讨论】:

    标签: shell unix csv awk nawk


    【解决方案1】:

    我使用了将多行分隔的一组记录转换为以~分隔的单行的逻辑 然后您可以在此之上编写一个逻辑将其转换为 csv 文件(我还没有这样做)

    cat ip_file.txt | tr '\n' '~' | tr '[' '\n'
    

    注意:假设 [ 不会出现在记录之间

    【讨论】:

    • 不,伙计。 ..这只是破坏了我已经创建的格式!
    • 我们可以使用匹配功能来实现吗?我只是感到困惑和挣扎。如果像我这样的菜鸟开始从事一些严肃的事情,就会发生这种情况!
    【解决方案2】:

    我不得不承认这是一个有点复杂的场景,你必须处理多个行字段,并且我想到了以下要求:

    • 每个字段可能跨越多行
    • 输出需要特殊格式,这里是 CSV 格式,也就是逗号分隔的文本
    • CSV 的转义字符
    • 关于某些字段格式的一些假设,例如电话号码可能以 ph: 开头,地址号码可能以街道号码开头等

    这里有一个代码sn-p供你参考:

    #!/usr/bin/awk -f
    BEGIN{
        RS="\.\s* \[[0-9]+\]";
        FS="\n";
        OFS=",";
    }
    
    function find_next_field_until_regex(regex, i, result){
        result = "";
        for (; i < NF; i++){
            field = $i
            sub(/,/, "\,", field);
            sub(/^[ \t]*/, "", field);
            if (field ~ regex){
                break;
            }
            result = result field;
        }
        printf("%s%s", result, OFS);
        return i;
    }
    
    {
        if(NF>1){
            sub(/,/, "\,", $1);
            printf("%s%s", $1, OFS);
            i = 2;
            i = find_next_field_until_regex("^[0-9]+", i); #discription
            i = find_next_field_until_regex("^ph: ", i); #address
            i = find_next_field_until_regex("www\\.", i); #phone
            for (; i < NF; ++i){
                printf("%s", $i);
            }
        }
        printf("\n");
    }
    

    同时检查gist snippet

    【讨论】:

      【解决方案3】:
      awk '$1 ~ /\. \[/ {
       sub(/\. \[[0-9]*]/, "", $1)
       if ($2 ~ /^ *[0-9]/) $2 = OFS$2
       n = split($0, a, OFS)
       while (a[3] !~ /^ *[0-9]/)
       {                       
        a[2] = a[2]a[3]
        for (i=3; i<=n; ++i) a[i]=a[i+1]
        --n                              
       }   
       print a[1],a[2],a[3],a[4],a[5] }' RS= FS='\n' OFS='|' Myfile > excel.csv
      

      【讨论】:

        猜你喜欢
        • 2012-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-08
        • 1970-01-01
        • 1970-01-01
        • 2016-05-03
        相关资源
        最近更新 更多