从 .csv 文件中读取值并使用 Shell 脚本执行计算

问题描述

请帮助我解决这个问题。
如何使用 Shell Scripting 执行以下操作(算术计算)。

sample1.csv

Assets,3,4,5
Loans,5,6
reported_activity,7,8,10

sample2.csv

credit,6,9
debit,13,8
affilate,9,5

sample1.csv

获取所有第一列值
3
4
7

& 从 sample2.csv 文件获取第一列值

6
13
9

然后使用公式计算:

Assets + ( loans + affiliate *-1) + reported_activity + (credit-debit)
                         

     3 +( 4*-1)+7 (6-13)
                              =3-4+7-7
                              = -1
                      

同样,需要对 .csv 文件的 col2 和 col3 进行算术计算。

解决方法

您可以转置 csv 文件并使用 awk 处理它们。您可以相应地修改打印语句中的公式。

paste -d" " <(rs -c',' -C -T < sample1) <(rs -c',' -C -T < sample2) | awk 'NR>1 {print $1+$2-$6+$3+$4-$5}'

不使用粘贴命令的替代方法

cat sample1 sample2 | rs -c,-C -T | awk 'NR>1 {print $1+$2-$6+$3+$4-$5}'

粘贴命令将连接这两个文件,您将拥有一个包含所有列的最终文件。


由于 rs 仅在 BSD 系统中可用,下面的代码片段使用 awk 来转置输入。借用这个SO answer

的转置代码
BEGIN { FS=OFS="," }
{
    for (rowNr=1;rowNr<=NF;rowNr++) {
        cell[rowNr,NR] = $rowNr
    }
    maxRows = (NF > maxRows ? NF : maxRows)
    maxCols = NR
}
END {
    for (rowNr=1;rowNr<=maxRows;rowNr++) {
        for (colNr=1;colNr<=maxCols;colNr++) {
            printf "%s%s",cell[rowNr,colNr],(colNr < maxCols ? OFS : ORS)
        }
    }
}

将上述文件另存为transpose.awk并如下运行

awk -f transpose.awk sample1.csv sample2.csv | awk -F,'NR>1 {print $1+$2-$6+$3+$4-$5}'
,

加上肖恩所说的,我认为你的计算是错误的。

替换公式 (loans + affiliate *-1) 的这一部分中的第二列值,我们得到 (4 + 9 * -1),即 -5(或者,如果您不关心 order of operations,它可能是 -13,但永远不会是 -4

也就是说,这段代码可以解决问题:

cat sample*.csv > samples.csv

IFS=',' read -r -a Assets <<< "$(grep Assets samples.csv)"
IFS=',' read -r -a Loans <<< "$(grep Loans samples.csv)"
IFS=',' read -r -a reported_activity <<< "$(grep reported_activity samples.csv)"
IFS=',' read -r -a credit <<< "$(grep credit samples.csv)"
IFS=',' read -r -a debit <<< "$(grep debit samples.csv)"
IFS=',' read -r -a affilate <<< "$(grep affilate samples.csv)"

for ((i = 1 ; i < ${#Assets[@]} ; i++)); do
        echo -n "Column $i: "
        echo "$(( ${Assets[i]} + ${Loans[i]} - ${affilate[i]} + ${reported_activity[i]} + ${credit[i]} - ${debit[i]} ))"
done

rm -f samples.csv
$ bash samples.sh
Column 1: -2
Column 2: 15
Column 3: 17