大佬教程收集整理的这篇文章主要介绍了awk程序文件执行,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
由于我最后一个问题变得越来越长了,这里是当前代码级别的精简版本。
简介:我需要inputpipe道分隔的input文件,检查以确保所有适用的loggingtypes存在,添加缺less的任何内容,并validation/更正每个loggingtypes中的子字段数。
inputlogging:
AA|1234|ABCD|EDGFT|TR56BE|~BB||E5TGE|~CC|253641|84597|~DD|78HND|ACBE|||43|~EE|HISBL|78943|~FF|12345|SKIP|~GG|||TYBGFR AA|2345|CDEF|GFHIT|48UJKK|~CC||3FKTI
loggingtypes和子字段计数validation文件kNown_flds条目:
读行时,awk $行
从批处理Linux到Windows的awk和sed命令。 如何转换?
Linux命令行使用for循环和格式化结果
AA~5~req BB~2~opt CC~3~opt DD~6~opt EE~4~opt FF~2~skp GG~4~opt
当前脚本,没有子字段更正:
#!/usr/bin/awk -f BEGIN { FS=OFS="~" } FNR==NR { dflts[$1] = create_empty_field($1,$2) if( $3 ~ /req|opt/ ) fld_order[++fld_cnt] = $1 fld_rule[$1] = $3 next } { flds = "" j = 1 for(i=1; i<=fld_cnt; i++) { j = skip_flds( j ) if($j !~ ("^" fld_order[i])) fld = dflts[fld_order[i]] else { fld = $j; j++ } flds = flds (flds=="" ? "" : OFS) fld } print flds } function create_empty_field(name,cnt,fld,i) { fld = name for(i=1; i<=cnt; i++) { fld = fld "|" } return( fld ) } function skip_flds(fnum,Name) { name = $fnum sub(/|.*$/,"",Name) while(fld_rule[name] == "skp") { fnum++ name = $fnum sub(/|.*$/,Name) } return( fnum ) }
我最初尝试执行子字段的validation和更正:
#!/usr/bin/awk -f BEGIN { FS=OFS="~" } FNR==NR { dflts[$1] = create_empty_field($1,$2) if( $3 ~ /req|opt/ ) fld_order[++fld_cnt] = $1 fld_rule[$1] = $3 next } { flds = "" j = 1 for(i=1; i<=fld_cnt; i++) { j = skip_flds( j ) if($j !~ ("^" fld_order[i])) fld = dflts[fld_order[i]] else { fld = fix_sub($j,$2); j++ } flds = flds (flds=="" ? "" : OFS) fld } print flds } function create_empty_field(name,Name) } return( fnum ) } function fix_sub(rec,num,upd,cnt) { cnt=split(rec,a,"|")-1 upd="" if(cnt != num) {for(i=1;i<=$num;i++) upd = upd a[i] "|" } else { upd=$rec } return(upd) }
上面的结果在达到第二个loggingtypes时出错。 所以现在我知道我需要从kNown_flds文件中捕获第二个值,以便将其传递给fix_sub函数。
我会join:
sub_fld[$1] = $2
在FNR==NR部分,但除此之外,我的大脑是简单的炸,我不能前进。
我知道作为一个独立的, fix_sub区域工作。 现在我只需要从kNown_flds读取的值通过。
期望的输出是:
AA|1234|ABCD|EDGFT|TR56BE|~BB||~CC|253641|84597|~DD|78HND|ACBE|||43|~EE|HISBL|78943||~GG|||TYBGFR AA|2345|CDEF|GFHIT|48UJKK|~BB||~CC||3FKTI|~DD||||||~EE||||~GG|||
原始问题: 用于格式化pipe道分隔的分段文件的UNIX SHell Script解决scheR_464_11845@e
根据共同的2列正确join两个文件
如何获得与bash处理器使用百分比?
AWK:有没有办法限制输出字段的宽度?
如何在awk中使用bash命令
试试这个修改的脚本:
#!/usr/bin/awk -f BEGIN { FS=OFS="~" } FNR==NR { dflts[$1] = create_empty_field($1,$2) if( $3 ~ /req|opt/ ) { fld_order[++fld_cnt] = $1 subfld_cnt[$1] = $2 } fld_rule[$1] = $3 next } { flds = "" j = 1 for(i=1; i<=fld_cnt; i++) { j = skip_flds( j ) if($j !~ ("^" fld_order[i])) fld = dflts[fld_order[i]] else { fld = fix_sub(j); j++ } flds = flds (flds=="" ? "" : OFS) fld } print flds } function get_field_name(fnum,Name) return( name ) } function create_empty_field(name,Name) { name = get_field_name(fnum) while(fld_rule[name] == "skp") { fnum++ name = $fnum sub(/|.*$/,Name) } return( fnum ) } function fix_sub(fnum,name,scnt,i,upd) { name = get_field_name(fnum) cnt = split($fnum,"|")-1 scnt = subfld_cnt[ name ] if(cnt != scnt) { for(i=1;i<=scnt;i++) upd = upd a[i] "|" return( upd ) } return( $fnum ) }
关键区别:
subfld_cnt[$1] = $2已被添加到FNR==NR块中的req|opt部分(处理kNown_flds文件)
增加了get_field_name()函数,它返回由它的fnum参数指定的字段的第一个子字段。
修改后的fix_sub()只接受fnum (所有其他变量都是本地函数),并根据需要修改子字段的数量。 现在对它的调用只需要在fix_sub(j)使用j参数。
fix_sub()更改的细分:
name = get_field_name(fnum)@L_801_39@查找的字段名称
split $fnum ,并得到分裂的计数(离开你的-1调整)
scnt = subfld_cnt[ name ]从已添加到kNown_flds文件处理中的数组中@L_801_39@所需的字段数。 这是你失踪的主要部分。
当cnt != scnt修复子域时。
留在你的upd设置代码中,但删除了upd = "" – 这已经完成了局部变量。
个人喜好 – 直接返回值而不是else值。
我得到以下内容:
AA|1234|ABCD|EDGFT|TR56BE|~BB||~CC|253641|84597|~DD|78HND|ACBE
43|~EE|HISBL|78943 ||~GG
TYBGFR| AA|2345|CDEF|GFHIT|48UJKK|~BB||~CC||3FKTI|~DD
~EE
|~GG
|
这不完全符合您所需的输出。 最后的区别在于| 在GG领域。 我认为你想要的输出是缺少的。 否则,最终字段的最后一个管道只需要在所有其他处理之后被丢弃。
以上是大佬教程为你收集整理的awk程序文件执行全部内容,希望文章能够帮你解决awk程序文件执行所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。