我在cmd.awk中有以下代码:
BEGIN {FS=","}
{
if(FNR==1) print $0",Header";
else if (FNR>1)
{
if($79==0 && $80==0 && $81==0) print $0",0";
else if ($80==0 && $81!=0) print $0","($79-$81)/$81;
else if ($81==0 && $80!=0) print $0","($79-$80)/$80;
else if ($81==0 && $80==0 && $79!=0) print $0",10";
else if ($81!=0 && $80!=0) print $0","(($79-$80)/$80)+(($80-$81)/$81);
}
}
当我执行以下命令时:
awk -f cmd.awk input.txt
它执行所需的操作(在AWK脚本中指定)并提供所需的结果。
但是在这个脚本中,输入txt文件的所有列都是基于column_index访问的,即$ 79,$ 80,$ 81等。
我的要求是我需要使用这个脚本作为一个函数,它需要79美元,80美元,81美元和Header(在脚本中给出)作为参数,执行操作并将结果存储在新添加的列中,列名为Header和将新内容存储到输出文件中。但我只允许以列标题的形式指定参数而不是列索引,即我的函数调用必须是这样的:
cmd(column_header1, column_header2, column_header3,new_header)
并且cmd()的函数定义必须执行上面awk脚本中提到的操作。
有没有办法做到这一点?请记住,我对awk很新。提前谢谢。
我的输入文件包含150列和超过50M行。该文件的样本如下:
RN,DATE,ID,PRE_M1,PRE_M2,GALV,GALG,PRE_M5.........................TOTAL
0624873840,2016/04/28,201610,1618,0,0,0,Active,.................12234
0747269250,2016/02/02,201610,227,93,0,0,Daat,....................99988
输入文件包含numeric,character类型的列。在上面的AWK脚本中访问的列都是数字类型。
所需输出文件的示例如下:
RN,DATE,ID,PRE_M1,PRE_M2,GALV,GALG,PRE_M5.........................TOTAL,Header
0624873840,2016/04/28,201610,1618,0,0,0,Active,.................12234,10
0747269250,2016/02/02,201610,227,93,0,0,Daat,....................99988,0
请注意,新列将附加到名称为" Header"的文件中。此列包含输入文件的每一行的AWK脚本的结果。
答案 0 :(得分:0)
# --- for your sample test ----------
column_1=1;column_2=2;column_3=3;new_header="Header"
awk -v Col1=${column_1} -v Col2=${column_2} -v Col3=${column_3} -v NewH="${new_header}" -F ',' '
BEGIN { OFS = FS }
FNR == 1 {
$(NF + 1) = NewH
print $0
next
}
{
if ( ! $Col1 && ! $Col2 && ! $Col3) NewV = 0
else if ( ! $Col2 && $Col3 ) NewV = ($Col1-$Col3)/$Col3
else if ( ! $Col3 && $Col2 ) NewV = ($Col1-$Col2)/$Col2
else if ( ! $Col3 && ! $Col2 && $Col1 ) NewV = 10
else if ( $Col3 && $Col2) NewV = (($Col1-$Col2)/$Col2)+(($Col2-$Col3)/$Col3)
print $0
}' YourFile
var == 0
与if中的! var
相同(您可以保留您的版本以提高可读性);
(这是在线人员的指令分隔符)你可以直接捕获awk中的参数,但与使用-v调用awk相比有点重要
答案 1 :(得分:0)
我认为你可以简化它,没有输入文件所以飞行盲目......
假设感兴趣的列是连续的并且字段都是数字,只需提供起始地址
$ awk -F, -v s=79 'BEGIN {OFS=FS}
NR==1 {$(NF+1)="Header"}
NR >1 {v1=$s; v2=$(s+1); v3=$(s+2)
if(!v2 && !v3) $(NF+1) = v1?10:0
else $(NF+1) = v3?(v1-v3)/v3:0 + v2?(v1-v2)/v2:0}1' file
参数列名称可以写为
$ cols="c1,c2,c3"; header="Header"
$ awk -F, -v cols="$cols" -v hdr="$header" '
BEGIN {OFS=FS}
NR==1 {n=split(cols,cn);
for(i=1;i<=NF;i++)
for(j=1;j<=n;j++)
if($i==cn[j]) c[++k]=i;
$(NF+1)=hdr}
NR >1 {v1=$c[1]; v2=$c[2]; v3=$c[3]
if(!v2 && !v3) $(NF+1) = v1?10:0
else $(NF+1) = v3?(v1-v3)/v3:0 + v2?(v1-v2)/v2:0}1' file
id,c1,c2,c3,Header
1,0,0,0,0
2,0,0,1,-1
3,0,1,0,-1
4,0,1,1,-1
5,1,0,0,10
6,1,0,1,0
7,1,1,0,0
8,1,1,1,0
用于给定的输入文件
id,c1,c2,c3
1,0,0,0
2,0,0,1
3,0,1,0
4,0,1,1
5,1,0,0
6,1,0,1
7,1,1,0
8,1,1,1
<强>解释强>
n=split(cols,cn)
使用相同的FS分隔符将字符串“cols”拆分为数组“cn”。元素的数量将被返回并分配给“n”。
1
是{print}