【问题标题】:Awk to format csv files | unix | Solaris | awkawk 格式化 csv 文件 | Unix |索拉里斯 | awk
【发布时间】:2018-02-16 05:11:29
【问题描述】:

我有多个 csv 文件,如下所示:

~/Prod/Jcs/BIN/Dash_PPLP/load$ ls -lt *csv
-rw-rw-r--   1 tellus   tellus        81 Sep  7 14:27 extraction_MBBSCS_PPL_USAGE_IMPORT.csv
-rw-rw-r--   1 tellus   tellus        83 Sep  7 14:27 extraction_MBBSCS_PPL_INVOICE_IMPORT.csv
-rw-rw-r--   1 tellus   tellus        71 Sep  7 14:27 extraction_INVOICE.csv
-rw-rw-r--   1 tellus   tellus        69 Sep  7 14:27 extraction_USGRERUN.csv
-rw-rw-r--   1 tellus   tellus        69 Sep  7 14:27 extraction_USG.csv
-rw-rw-r--   1 tellus   tellus        72 Sep  7 14:27 extraction_LIA.csv
-rw-rw-r--   1 tellus   tellus        74 Sep  7 14:27 extraction_MSISDN.csv

打开一个文件

cat extraction_LIA.csv
PPL_LIABILITY,2468705,Fri Sep 01 06:56:41 2017,Fri Sep 01 06:58:33 2017

格式是我要监控的每个流的名称、行、开始时间和结束时间,以便使它们“可加载”到 ORACLE 表中。

我已经制作了一个这样的脚本来进行转换并覆盖它们,如下所示:

cat transform_to_load.bash
#!/bin/bash
csv_files=$(ls *.csv)
for i in $csv_files
do
x=$(nawk 'BEGIN { OFS=","; FS=","} {split($3,a," ");split($3,b," ")}
{$3=a[3]"/"a[2]"/"a[5]" "a[4];$4=b[3]"/"b[2]"/"b[5]" "b[4]}
{print}' $i)
echo $x > $i
done

问题出在我的 nawk 上:

x=$(nawk 'BEGIN { OFS=","; FS=","} {split($3,a," ");split($3,b," ")}
    {$3=a[3]"/"a[2]"/"a[5]" "a[4];$4=b[3]"/"b[2]"/"b[5]" "b[4]}
    {print}' $i)

产生以下(开始时间与结束时间相同)

tellus@proetl01:~/Prod/Jcs/BIN/Dash_PPLP/load$ cat extraction_LIA.csv
PPL_LIABILITY,2468705,01/Sep/2017 06:56:41,01/Sep/2017 06:56:41

我想要实现的是使用 nawk (SunOS) 对它进行相应的格式化:

PPL_LIABILITY,2468705,01/Sep/2017 06:56:41,01/Sep/2017 06:58:33

你能帮我用我的 nawk 输出正确的格式吗?

非常感谢!

【问题讨论】:

    标签: bash csv unix awk


    【解决方案1】:

    你快接近目标了,需要稍微修正一下

    原因:

    因为在你的代码中,

    {split($3,a," "); split($3,b," ")}
                             ^
                         So you get same result in end time
    

    改正如下

    解决方案:

    {split($3,a," "); split($4,b," ")}
                             ^
                          Fourth Column will be used
    

    同时,如果你有兴趣,你可以像下面这样简化,

    不需要

    • csv_files=$(ls *.csv)
    • x=$(nawk '{..}')
    • echo $x > $i

    简化版

    $ cat test.sh
    #!usr/bin/env bash
    
    for i in *.csv; do
    
    # Better Prefer 
    # /usr/xpg4/bin/awk or /usr/xpg6/bin/awk 
    
        nawk '
              BEGIN{
                    FS=OFS=","
              }
              function format_dt(v, a){
                  split($v,a,/ /); 
                  $v=a[3]"/"a[2]"/"a[5]" "a[4]
              }
              { 
                  format_dt(3); 
                  format_dt(4) 
              }1
             ' "$i" >tmpfile && mv tmpfile "$i"
    done
    

    【讨论】:

    • 嘿!非常感谢,所以将其调整为 4 美元即可解决问题,对吗??
    • @tln_jupiter :是的,你可以看到$3 表示第三个字段/列
    • @tln_jupiter,很高兴知道它有帮助
    • @tln_jupiter:你也可以这样尝试:awk 'BEGIN{FS=OFS=","}function format_dt(v, a){split($v,a,/ /); $v=a[3]"/"a[2]"/"a[5]" "a[4]}{ format_dt(3); format_dt(4) }1' file
    猜你喜欢
    • 1970-01-01
    • 2021-12-13
    • 2014-06-22
    • 1970-01-01
    • 2015-11-09
    • 2014-10-12
    • 2020-05-29
    • 2019-05-06
    相关资源
    最近更新 更多