代码之家  ›  专栏  ›  技术社区  ›  crafter

gawk FIELDVIDTHS转换为CSV,但某些字段将美分转换为美元

  •  0
  • crafter  · 技术社区  · 3 年前

    我正在将从银行收到的固定宽度的交易详细信息文件转换为CSV文件。

     gawk '$1=$1' FIELDWIDTHS='1 8 12 23 6 6 6 7 13 9 3 10 1 2 3 1 3 1 1 2 6 3 12 3 3 1 2 9 19 140  ' OFS=, $f  >> $csvfilename
    

    有些字段是货币字段,以美分为单位列出。 例如,倒数第二个字段的值为“1234567”。 但是,我希望输出的值是“12345.67”。

    我正在寻找如何进行转换。有点像

    FIELDWIDTHS='1 8 12 23 6 6 6 7.2 13 '
    

    举个例子。接收到以下输入

    1000000000000027302080000000541282******8764211118211118211118006483000000000016870000000000pu 831712 DR90 020N000000000323132106663755
    0000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    生成的CSV文件为

    1000000000000027302080000000448387******609821111521111621111601204560000000051580000000000,PU ,754045,DR,90,20N,0,00000000 321131912995587, 0,0,00,000000000,0000000000000000000,0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    第8个字段的值为“0120456”。 我希望生成的逗号分隔文件中的值为“01204.56”

    0 回复  |  直到 3 年前
        1
  •  1
  •   Nic3500 tpdi    3 年前

    这里有一个我认为你可以使用或调整的解决方案。

    Bash脚本:

    #!/bin/bash
    
    line="1000000000000027302080000000541282******876421111821111821111800648300000000021687000000000PU 831712     DR90 020N000000000323132106663755 0000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    
    echo "$line" | awk -f so.awk
    

    so.awk

    BEGIN {
        FIELDWIDTHS = "1 8 12 23 6 6 6 7 13 9 3 10 1 2 3 1 3 1 1 2 6 3 12 3 3 1 2 9 19 140"
    }
    
    {
        # Print first 7 fields
        for (i=1; i<=7; i++) {
            printf "%s,", $i
        }
    
        # Print 8th field
        firstXchars = substr($8, 0, length($8)-2)
        lasttwochars = substr($8, length($8)-1)
        printf "%s.%s,", firstXchars, lasttwochars
    
        # Print the rest of fields, except the last one (I do not want the , for the last one)
        for (j=9; j<=NF-1; j++) {
            printf "%s,", $j
        }
    
        # Print the last field
        print $NF
    }
    

    它的作用

    • 打印前7个字段,分隔为 , ,没有更改
    • 对于第8个字段,提取字符 除了 最后两个
    • 对于第8个字段,提取最后两个字符
    • 打印字段8 (except last two).(last two),
    • 打印除最后一个字段外的所有剩余字段 ,
    • 打印最后一个字段

    输出

    $ ./so.bash 
    1,00000000,000002730208,0000000541282******8764,211118,211118,211118,00648.30,0000000021687,000000000,PU ,831712    , ,DR,90 ,0,20N,0,0,00,000003,231,32106663755 ,000,000,0,00,000000000,0000000000000000000,000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
                                                                         ^^^^^^^^
    

    笔记 ^^^^^^^^ 不是输出的一部分,我只是突出显示字段8

    使用此处突出显示的用于管理字段8的方法,您可以调整脚本以适应您的实际数据和输出要求。

        2
  •  1
  •   Ed Morton    3 年前

    听起来这就是你想要做的:

    $ cat file
    foo12345bar
    
    $ awk -v FIELDWIDTHS='3 5 3' -v OFS=',' '{sub(/..$/,".&",$2)} 1' file
    foo,123.45,bar