【问题标题】:Read values from .csv files and perform calculations using Shell Scripting从 .csv 文件中读取值并使用 Shell 脚本执行计算
【发布时间】:2021-08-31 03:21:14
【问题描述】:

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

sample1.csv

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

sample2.csv

credit,6,7,9
debit,13,5,8
affilate,9,4,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 执行算术计算。

【问题讨论】:

标签: linux bash shell csv scripting


【解决方案1】:

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

替换公式(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

【讨论】:

  • sample1 和 sample2 csv 文件包含真实场景中的浮点数在执行上述脚本时,我收到错误:语法错误:算术运算符无效(错误标记为“.387)
  • @blackhole bash 不做浮点运算,只做整数。见mywiki.wooledge.org/BashFAQ/022
【解决方案2】:

您可以转置 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 系统中可用,下面的 sn-p 使用 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}'

【讨论】:

  • 我想我的机器需要安装rs
  • 哎呀.. rs 是一个似乎只在像 MacOS 这样的 BSD 系统中发现的命令。将更新我的答案。
猜你喜欢
  • 2013-06-14
  • 2017-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-11
  • 2019-02-10
  • 1970-01-01
相关资源
最近更新 更多