![如何在kornshell中按特定日期对指定列的值求和?](https://linux22.com/image/144285/%E5%A6%82%E4%BD%95%E5%9C%A8kornshell%E4%B8%AD%E6%8C%89%E7%89%B9%E5%AE%9A%E6%97%A5%E6%9C%9F%E5%AF%B9%E6%8C%87%E5%AE%9A%E5%88%97%E7%9A%84%E5%80%BC%E6%B1%82%E5%92%8C%EF%BC%9F.png)
我正在使用一个独特的验证框架来验证数据。对于每个验证作业,都有一个 SQL 作业以及一个附带的 KSH 作业 (kornshell)。 SQL查询数据库中的某些内容,KSH需要使用与DB(SQL)相同的逻辑来查询数据文件。
我当前的 SQL 语句按我硬编码的日期查询聚合列的总和,并给出一个值。如何在下面的 KSH 文件中复制该内容?
目前,我的 KSH 代码如下所示:
cat /textfile.txt | > ${OUTPUT_FILE}
因此,这个 KSH 需要做的是给我指定日期的特定列的总和。日期将会有多个记录。
示例数据:
Date | Money
--------------
1/1/15 : $15
2/2/15 : $14
3/3/16 : $25
etc... : etc...
预期输出:2015 年 1 月 1 日至 2015 年 1 月 31 日的总和(金钱)。
答案1
确切的语法将取决于确切的输入。如果值字段总是开头<space><dollar>
,那么我们可以使用 awk 语句:
awk -F: '$2 ~ /^ \$/ { a[$1]+=substr($2,3)} END {for (b in a) { print b"$"a[b]}}'
例如
awk -F: '$2 ~ /^ \$/ { a[$1]+=substr($2,3)} END {for (b in a) { print b"$"a[b]}}' testfile.txt
3/3/16 $25
2/2/15 $14
1/1/15 $15
注意:如果分隔符确实是 a|
而不是 a,:
那么您需要执行awk -F'|' ...
.
它的工作方式是:
$2 ~ /^ \$/
-- 对于第二个字段开始的每一行<space><dollar>
{ a[$1]+=substr($2,3)}
-- 将第二个字段的内容(去掉前两个字符)添加到按日期索引的数组中
END {for (b in a) { print b"$"a[b]}}'
-- 文件结束后,浏览我们找到的所有日期,并打印总数。
因此,基本上,该a
数组按日期索引并包含该日期的值的总和。
答案2
好吧,如果您在 ksh 中需要它,该示例可能会帮助您:
我使用过的数据文件:
Date | Money
--------------
1/1/15 : $15
2/2/15 : $14
3/3/16 : $25
1/2/15 : $10
2/1/15 : $35
3/2/15 : $7
代码 :
#!/bin/ksh
typeset -A SUM_ARRAY
IN_FILE="$1"
if [[ -z $IN_FILE ]]; then
print "Usage : script.sh {input filename}"
exit
fi
while read line;
do
temp_array=($line)
if [[ ! ${temp_array[0]} =~ ^(-*)$ && ${temp_array[0]} != "Date" ]]; then
idx=$(date -d ${temp_array[0]} +"%Y%m")
SUM_ARRAY[$idx]=$((${SUM_ARRAY[$idx]}+${temp_array[2]#\$*}))
fi
done < $IN_FILE
print "YearMonth\tSum"
for idx in ${!SUM_ARRAY[@]}; do
print "$idx\t\t${SUM_ARRAY[$idx]}"
done
结果 :
YearMonth Sum
201501 25
201502 49
201503 7
201603 25