2017-04-11 58 views
2

我有一个像下面这样的文本文件。如何格式化不以分隔符分隔的值文件?

DATE    HOUR   LCU    MVS    ACTIVE   
            NUMBER   SYSTEM   RATE   
                ID       
    2017-04-03     0   004D PROD     12.15 
    2017-04-03     0   005F PROD     9.82 
    2017-04-03     0   0060 PROD     5.99 

如果输入不是csv或tsv或空格分隔,我怎样才能在列中放入值和标题?

我试过sed,awk,熊猫,没有结果。 不同的列

之间没有常客模式,我想这样的一个文件:

DATE       HOUR   LCU MVS    ACTIVE   
              NUMBER SYSTEM   RATE   
                ID       
    2017-04-03     0   004D PROD   12.15 
    2017-04-03     0   005F PROD   9.82 
    2017-04-03     0   0060 PROD   5.99 

UPDATE 这将是巨大的显然将其改造成一个CSV,但考虑到丢失的字段。

DATE,HOUR,LCU,MVS,ACTIVE  
,,NUMBER,SYSTEM,RATE   
,,,ID,      
2017-04-03,0,004D,PROD,12.15 
2017-04-03,0,005F,PROD,9.82 
2017-04-03,0,0060,PROD,5.99 
+0

它是空格和制表符的混合吗? –

+0

这个文件是什么?它来自哪里?它被某些东西分隔,否则它将是一个没有格式的连续字符串。 2017-04-030004DPROD12.15 2017-04-030005FPROD9.82 2017-04-0300060PROD5.99 根据来连接这个工作,它的空间分隔的......除非你刚刚输入其送到看起来像输出。 – Stese

+0

标题中的空格和制表符的组合,只是空间中的空格 –

回答

0

试试这个:

echo "DATE,HOUR,LCU_NUMBER,MVS_SYSTEM_ID,ACTIVE_RATE" > out.csv 
tail -n+4 file.txt | awk 'BEGIN{OFS=","}{print $1,$2,$3,$4,$5}' >> out.csv 
+0

它可以工作,但我不能回显你的第一行 –

0

如果你可以手动添加行2和3,使用下面 -

$ awk '(NR==1 || NR > 3) {printf "%-32s %-10s %-6s %-18s %-10s\n", $1,$2,$3,$4,$5}' file 
DATE        HOUR  LCU MVS    ACTIVE 
2017-04-03      0   004D PROD    12.15 
2017-04-03      0   005F PROD    9.82 
2017-04-03      0   0060 PROD    5.99 
+0

我不能,不幸的是它来自一个SQL查询,我有只是我写的形式的输出 –

0

大熊猫的解决方案

您的文件似乎是一个固定宽度格式的文件,所以我们可以使用Pandas.read_fwf()方法:

import pandas as pd 

pd.read_fwf('/path/to/input_file.txt').to_csv('c:/temp/out.csv', index=False) 

结果('c:/temp/out.csv'):

DATE,HOUR,LCU,MVS,ACTIVE 
,,NUMBER,SYSTEM,RATE 
,,,ID, 
2017-04-03,0.0,004D,PROD,12.15 
2017-04-03,0.0,005F,PROD,9.82 
2017-04-03,0.0,0060,PROD,5.99 
0

你的数据使用固定宽度的字段和处理,在GNU AWK的方式只是以指定在FIELDWIDTHS变量中的每个字段的宽度:

$ cat tst.awk 
BEGIN { FIELDWIDTHS="12 21 16 9 21"; OFS="," } 
{ 
    for (i=1;i<=NF;i++) { 
     gsub(/^\s+|\s+$/,"",$i) 
     printf "%s%s", $i, (i<NF ? OFS : ORS) 
    } 
} 

$ awk -f tst.awk file 
DATE,HOUR,LCU,MVS,ACTIVE 
,,NUMBER,SYSTEM,RATE 
,,,ID, 
2017-04-03,0,004D,PROD,12.15 
2017-04-03,0,005F,PROD,9.82 
2017-04-03,0,0060,PROD,5.99 

这创造了更多有用的CSV头,但:

$ cat tst.awk 
BEGIN { FIELDWIDTHS="12 21 16 9 21"; OFS="," } 
/[0-9]/ { 
    if (!inData++) { 
     for (i=1;i<=NF;i++) { 
      printf "%s%s", hdr[i], (i<NF ? OFS : ORS) 
     } 
    } 
    for (i=1;i<=NF;i++) { 
     gsub(/^\s+|\s+$/,"",$i) 
     printf "%s%s", $i, (i<NF ? OFS : ORS) 
    } 
    next 
} 
{ 
    for (i=1;i<=NF;i++) { 
     gsub(/^\s+|\s+$/,"",$i) 
     if ($i != "") { 
      hdr[i] = (i in hdr ? hdr[i] "_" : "") $i 
     } 
    } 
} 

$ awk -f tst.awk file 
DATE,HOUR,LCU_NUMBER,MVS_SYSTEM_ID,ACTIVE_RATE 
2017-04-03,0,004D,PROD,12.15 
2017-04-03,0,005F,PROD,9.82 
2017-04-03,0,0060,PROD,5.99 

如果您的输入实际上有空白字符和制表符的混合,那么首先运行它通过pr -e -t将所有制表符转换为空白相对间距。