我需要解析 CSV 文件的某些字段,并根据匹配的模式,我需要将字段添加在一起。我已成功设置变量,但需要帮助弄清楚如何在可能有 1-20 个变量时添加它们。 (或者可能是另一种更简单的方法来解决这个问题。)
源文件内容示例:
Server-Name,Volume-Name,Vol-Size,Logical-Space-In-Use
FTWTRAQNETSQL01,FTWTRAQNETSQL01_e,2008,1989
FTWTRAQNETSQL01,FTWTRAQNETSQL01_f,106,63.698
FTWTRAQNETSQL02,FTWTRAQNETSQL02_e,2008,1989
FTWTRAQNETSQL02,FTWTRAQNETSQL02_f,106,4.155
ftwvocmpsqln01,ftwvocmpsqln01_1,1002,21.047
ftwvocmpsqln01,ftwvocmpsqln01_2,104,55.379
ftwspsqln02,ftwspsqln02_H,501,0
ftwvocmpsqln02,ftwvocmpsqln02_1,1002,20.732
ftwvocmpsqln02,ftwvocmpsqln02_2,104,55.380
每个唯一服务器名称的输出应为一行,并添加所有字段 3 值和所有字段 4 值。服务器可以有多个卷,有些多达 20 个。所需的文件输出为:
Server-Name,Vol-Size,Logical-Space-In-Use
FTWTRAQNETSQL01,2114,2052.698
FTWTRAQNETSQL02,2114,1993.155
ftwvocmpsqln01,1106,76.426
ftwspsqln02,501,0
ftwvocmpsqln02,1106,76.112
我可以在 Excel 中大约 7 秒内完成此操作,但到目前为止还没有找到使用 bash(或其他 shell)实现自动化的解决方案。
这是我到目前为止的代码,只查看字段 3。它为唯一服务器的每次迭代正确设置变量,但我不知道如何使用可变数量的变量进行加法。
for i in $( awk -F , '{print $1}' $REPORT | grep -v Server-Name | uniq )
do
c=0
for num in $( grep $i $REPORT | awk -F , '{print $3}' )
do
eval "var$c=$num";
c=$((c+1));
done
done
答案1
使用 GNU datamash:
$ datamash -t, --header-in groupby 1 sum 3,4 < file.csv
FTWTRAQNETSQL01,2114,2052.698
FTWTRAQNETSQL02,2114,1993.155
ftwvocmpsqln01,1106,76.426
ftwspsqln02,501,0
ftwvocmpsqln02,1106,76.112
答案2
不是 shell,而是“unix way”:
awk -F',' 'NR==1; NR>1{s3[$1]+=$3; s4[$1]+=$4} END { for(i in s3){printf("%s,%s,%s\n",i,s3[i],s4[i])} }' file
输出的顺序(可能)与输入的顺序不匹配。
描述:
awk # use awk.
-F',' # set the field separator as comma (,)
' # start an awk script.
NR==1; # print first line (header)
NR>1{ # for lines other than first
s3[$1]+=$3; # add values on third field
s4[$1]+=$4 # add values on fourth field
} # close the previous {
END { # after all lines have been read
for(i in s3){ # for each index of the array
# (all unique values of field $1)
printf("%s,%s,%s\n",i,s3[i],s4[i]) # print values.
} # close the for loop.
} # close the END loop.
' file # end script code and name the file.
答案3
使用 Miller ( mlr
) 计算两列 和 的总和Vol-Size
,Logical-Space-In-Use
按字段分组Server-Name
:
$ mlr --csv stats1 -a sum -f Vol-Size,Logical-Space-In-Use -g Server-Name file
Server-Name,Vol-Size_sum,Logical-Space-In-Use_sum
FTWTRAQNETSQL01,2114,2052.698000
FTWTRAQNETSQL02,2114,1993.155000
ftwvocmpsqln01,1106,76.426000
ftwspsqln02,501,0
ftwvocmpsqln02,1106,76.112000