Shell 解析和修改文件内容
我有一个应用程序,它生成包含由逗号(,)分隔的各种数据行的文件 例如:Shell 解析和修改文件内容,shell,parsing,awk,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,roo
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
第一次查询:有时文件会遗漏第四列状态
中的信息,这些信息可以是动作版本,修改版本,切换版本或对置屏幕版本。我想在缺少状态的文件中添加一个额外的逗号(,)
第二个查询: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
不确定哪一个是流程密集度最低的
我正在RHEL6.7操作系统上使用shell脚本,测试正常
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
我考的不错
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
分两步进行
对于不包含$4
作为版本的行,请在实际$4
之前插入,
。由于这里的,
是输入和输出字段分隔符,因此不能直接使用FS
对于日期列上的所有行,即在$6
上,使用
上的split()
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
分两步进行
对于不包含$4
作为版本的行,请在实际$4
之前插入,
。由于这里的,
是输入和输出字段分隔符,因此不能直接使用FS
对于日期列上的所有行,即在$6
上,使用
上的split()
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
您可以使用此awk
:
awk 'BEGIN{FS=OFS=","} NR>1 && NF<8 && $4 !~ /VER$/{$4 = OFS $4}
{sub(/\.[0-9]{3},/, ",")} 1' file
您可以使用此awk
:
awk 'BEGIN{FS=OFS=","} NR>1 && NF<8 && $4 !~ /VER$/{$4 = OFS $4}
{sub(/\.[0-9]{3},/, ",")} 1' file
显示所显示输入的预期输出。@anubhava谢谢,我完全忘记了。我已编辑我的查询。上次编辑有一些错误。我已经纠正了。@Marcos:您的输出仍然不正确server4
中仍然有000
date@Inian更新。显示所显示输入的预期输出。@anubhava谢谢,我完全忘记了。我已编辑我的查询。上次编辑有一些错误。我已经纠正了。@Marcos:您的输出仍然不正确server4
中仍然有000
date@Inian更新。我已经测试了它,它不起作用,因此尝试了“$4”和$4。使用我的CMD进行测试第一个awk语句起作用了…我之前写的有点错误。另外,第二个awk语句有一个temp
,不确定是否需要。我运行了两个awk语句,没有temp
,但它都工作了。我已经测试过了,但没有工作,因此尝试了“$4”和$4。用我的CMD进行测试第一个awk语句工作了……我之前写的有点错误。另外,第二个awk语句有一个temp
,不确定是否需要。我运行了两个awk语句,没有temp
,它运行正常。这使得第一个server3
和第二个server1
的行具有000
哦,是的,没错<代码>$6
也可以是$5
。编辑时假设只有具有毫秒值的字段@anubhava它不会更新第4列的第1行。另外,awk语句的第二部分不起作用,它没有替换.000
。在我显示的输出中没有.000
。第一行的第四列已经有ACT\u VER
,因此不需要更新。这使得第一行的server3
和第二行的server1
都有000
哦,是的,没错<代码>$6
也可以是$5
。编辑时假设只有具有毫秒值的字段@anubhava它不会更新第4列的第1行。另外,awk语句的第二部分不起作用,它没有替换.000
。在我显示的输出中没有.000
。第1行的第4列已经有ACT\u VER
,因此不需要更新。