解析和修改文件内容

时间:2018-09-28 09:26:38

标签: shell parsing awk

我有一个应用程序,该应用程序生成的文件包含用逗号(,)分隔的各行数据。

例如:

hostname,file_name,type,status,size(b),date,owner(user),owner(group)
server1,/var,dir,ACT_VER,29987,2007-12-03 15:52:43.000,root,root
server2,/DATA_File.out,file,ACT_VER,299076487,2008-10-15 05:12:23.000,marcos,root
server3,/opt,dir,29987,2009-05-03 00:13:23.000,user1,group1
server4,/var/tmp/xxz.zip,file,MOD_VER,400,2007-12-03 15:52:43.000,root,root
server1,/usr,dir,34299876,2006-12-03 15:52:43.000,root,root
server3,/local/home,dir,MOD_VER,400,2009-05-03 00:13:23.000,user2,group1

预期输出:

hostname,file_name,type,status,size(b),date,owner(user),owner(group)
server1,/var,dir,ACT_VER,29987,2007-12-03 15:52:43,root,root
server2,/DATA_File.out,file,ACT_VER,299076487,2008-10-15 05:12:23,marcos,root
server3,/opt,dir,,29987,2009-05-03 00:13:23,user1,group1
server4,/var/tmp/xxz.zip,file,MOD_VER,400,2007-12-03 15:52:43,root,root
server1,/usr,dir,,34299876,2006-12-03 15:52:43,root,root
server3,/local/home,dir,MOD_VER,400,2009-05-03 00:13:23,user2,group1

第一个查询:有时文件会丢失第四列status中的信息,该列可以是ACT_VERMOD_VERTCH_VERCRT_VER。我想在缺少status的文件中添加一个逗号。

第二个查询:date列中的数据在`YYYY-MM-DD HH:MM:SS.MsMs(Ms =毫秒)中。我想忽略毫秒。

我正在awk中寻找其他东西来做这两者,而这在处理中是轻巧的,因为代码必须解析数百万行。

对于第一个查询,我尝试了此操作(以及该操作的几种替代方法),该操作不起作用

cat file | awk -F, 'BEGIN {OFS=","}{if ($4 !~ /VER/) $4=",$4";}{print $0}'

我还没有开始处理第二个查询。

我还想知道,是否应该在缺少*VER*时将整个文件放入数组并处理第4个元素以包含多余的逗号(,),并删除第6个元素中的.000

不确定哪一个将最少地处理过程。

我在RHEL 6.7 OS上使用shell脚本

3 个答案:

答案 0 :(得分:1)

分两步进行

  1. 对于不包含$4作为VER的行,请在实际,之前插入$4。由于,是此处的输入和输出字段分隔符,因此不能直接使用FS
  2. 对于日期列(即$6上的所有行,请使用split()上的.函数并打印不包含000的零件

    awk 'function splitdate(var) {
             n=split(var,a,".")
             return a[1] 
         } 
         BEGIN{ FS=OFS="," } 
         NR>1 && $4 !~ /VER/{ $4=","$4; $5=splitdate($5); print; next }
         { $6=splitdate($6) }1' file
    

答案 1 :(得分:1)

您可以使用此ngOnInit() { function topFunction() { ... } }

awk

awk 'BEGIN{FS=OFS=","} NR>1 && NF<8 && $4 !~ /VER$/{$4 = OFS $4}
     {sub(/\.[0-9]{3},/, ",")} 1' file

答案 2 :(得分:0)

我测试正常 GNU Awk 3.1.7

awk -F, 'BEGIN {OFS=","}{if ($4 !~ /VER/) $4=","$4;}{print $0}' temp|awk -F, 'BEGIN {OFS=","}{$6=substr($6,0,19)}{print}'
server1,/var,dir,ACT_VER,29987,2007-12-03 15:52:43,root,root
server2,/DATA_File.out,file,ACT_VER,299076487,2008-10-15 05:12:23,marcos,root
server3,/opt,dir,,29987,2009-05-03 00:13:23,user1,group1
server4,/var/tmp/xxz.zip,file,MOD_VER,400,2007-12-03 15:52:43,root,root
server1,/usr,dir,,34299876,2006-12-03 15:52:43,root,root
server3,/local/home,dir,MOD_VER,400,2009-05-03 00:13:23,user2,group1