awk + ​​printf:用“#######”替换长值

时间:2012-12-30 19:32:39

标签: bash awk printf

我从mysql中的查询中获取了一些数据,我需要将其转换为漂亮的表格。 然后我使用awk和printf来对齐列,格式化数字等。

cat /home/jm/mysql/pruebas/pruebat.txt | awk 'BEGIN { FS = ";" } ; {printf "%-'$A's %-'$B's %'\'''$C'd %'\'''$D'd %'\'''$E'd %'\'''$F'.2f %'\'''$F'.2f %'\'''$F'.2f\n", $1, $2, $3, $4, $5, $6, $7, $8 }' >> /home/jm/mysql/pruebas/prn.tx

当某些字段太长时(例如,太年之间的百分比变化为-12.345,67%),我的问题出现了。在这种情况下,我更愿意只显示######。 如果我在查询中使用case / when / then / end,我可以用字符串######替换long值,但是当awk + ​​printf将此字段作为十进制数字读取时,它显示0.00%而不是所需 ######。 有没有办法写“如果这个变量太长,只需打印######”? 谢谢,

JM

编辑:

我的源文件(忘记标题):

S_V;NO INVENTARIABLES;-41.7000;-67.5200;-25.8200;61.91846523;100.00000000;100.00000000
S_A;ARTICULOS PROMOCIONES;54.4400;631.3200;576.8800;1059.66201323;-1412.30712711;-19.76018501
S_B;PRODUCTOS TECNICOS;975.6000;1951.2000;975.6000;100.00000000;36.01476015;34.61254613
S_S;MATERIAL ELECTRICO;2237.6600;5103.2500;2865.5900;128.06190395;40.21030898;43.42859942

我的输出:

fam     nombre                               2011       2012        var        %   %mgn11   %mgn12
--------------------------------------------------------------------------------------------------
S_V     NO INVENTARIABLES                     -41        -67        -25    61.92   100.00   100.00
S_A     ARTICULOS PROMOCIONES                  54        631        576 1,059.66 -1,412.31   -19.76
S_B     PRODUCTOS TECNICOS                    975      1,951        975   100.00    36.01    34.61
S_S     MATERIAL ELECTRICO                  2,237      5,103      2,865   128.06    40.21    43.43

我的愿望(或类似):

fam     nombre                               2011       2012        var        %   %mgn11   %mgn12
--------------------------------------------------------------------------------------------------
S_V     NO INVENTARIABLES                     -41        -67        -25    61.92   100.00   100.00
S_A     ARTICULOS PROMOCIONES                  54        631        576   ######   ######   -19.76
S_B     PRODUCTOS TECNICOS                    975      1,951        975   100.00    36.01    34.61
S_S     MATERIAL ELECTRICO                  2,237      5,103      2,865   128.06    40.21    43.43

1 个答案:

答案 0 :(得分:3)

让我们首先用合理的shell + awk语法重写你的脚本,我能说得最好:

awk -F\; -v fmt="%-${A}s %-${B}s %'${C}d %'${D}d %'${E}d %'${F}.2f %'${F}.2f %'${F}.2f\n" '
{ printf fmt, $1, $2, $3, $4, $5, $6, $7, $8 }
' /home/jm/mysql/pruebas/pruebat.txt >> /home/jm/mysql/pruebas/prn.tx

现在,您遇到的问题是您的格式字符串专门用于打印数字,而实际上您要打印字符串,因此请使用sprintf创建数字然后如果您对结果更改不满意它是一个输出字符串。像这样(未经测试):

awk -F\; -v fmt="%-${A}s %-${B}s %'${C}d %'${D}d %'${E}d %'${F}.2f %'${F}.2f %'${F}.2f\n" '
BEGIN{ split(fmt,fmtA,/ /) }
{
    for (i=1;i<=NF;i++) {
       $i = sprintf(fmtA[i],$i)
       if (gsub(/[^[:space:]]/,"&",$i) > 6) {
           $i = "######"
       }
    }
    print
}
' /home/jm/mysql/pruebas/pruebat.txt >> /home/jm/mysql/pruebas/prn.tx