awk命令用于分隔记录并保存为csv

时间:2012-06-15 09:58:01

标签: shell unix csv awk nawk

嗨我实际上试图管理一个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的新东西...... 如果可能的话,任何人都可以帮助我...

3 个答案:

答案 0 :(得分:0)

我使用了将由多行分隔的一组记录转换为由〜分隔的单行的逻辑 然后你可以在此基础上编写一个逻辑来将它转换为csv文件(我还没有完成)

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

注意:假设[不会介入记录之间

答案 1 :(得分:0)

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

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

以下是供您参考的代码段:

#!/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

答案 2 :(得分:0)

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