【问题标题】:CSV file update using Shell script使用 Shell 脚本更新 CSV 文件
【发布时间】:2019-02-05 14:32:16
【问题描述】:

我对这些东西很陌生,真的需要一些帮助。

我正在尝试制作一个 shell 脚本,该脚本将从一个或多个数据库中提取数据,将其导出为 CSV,将数据合并到一个文件中,并将一些公式应用于文件,如 SUM 或检查数字之间的差异.只要公式仍将应用于新文件,我应该能够更新或替换文件。

到目前为止我得到了什么:

mysql -h host -u user -ppassword -P port 
"query" |tee file1.csv
# I didn't know how to have multiple queries for the same DB
mysql -h host2 -u user2 -ppassword2 -P port 
"query2" |tee file2.csv

sed -i 'li\FILE1' file1.csv #just to add a title
echo '' >> file1.csv #just to add a space at the end
sed -i 'li\FILE2' file2.csv 
echo '' >> file2.csv 
cat file1.csv file2.csv > file.csv

这是我的 file.csv 看起来如何但实际上包含更多相似单元格的示例:

       A         B       C
1   C.Installs      
2   date        
3   2019-02-01  100 
4   2019-02-02  131 
5   2019-02-03  222 
6   2019-02-04  180 
7   2019-02-05  213 
8           
9   A.Installs      
10  Date        
11  2019-02-01  23  
12  2019-02-02  42  
13  2019-02-03  34  
14  2019-02-04  35  
15  2019-02-05  21  

现在每次我运行 shell 命令时,它都应该更新/替换 file.csv,同时维护或重新添加特定单元格的公式。之前和之后的示例:

第一次运行 shell 脚本:

         A       B      C
1   C.Installs      
2   date        
3   2019-02-01  100 
4   2019-02-02  131 
5   2019-02-03  222 
6   2019-02-04  180 
7   2019-02-05  213 
8               846 #Formula of SUM for the 5 values
9   A.Installs      
10  Date        
11  2019-02-01  23  
12  2019-02-02  42  
13  2019-02-03  34  
14  2019-02-04  35  
15  2019-02-05  21  
16              155 #Formula of SUM for the 5 values
17          
18              691 #Formula of the difference between the two totals

Shell 脚本的第二次运行:

        A        B     C
1   C.Installs      
2   date        
3   2019-02-02  131 
4   2019-02-03  222 
5   2019-02-04  180 
6   2019-02-05  213 
7   2019-02-06  158 
8               904 #Formula of SUM for the 5 values
9   A.Installs      
10  Date        
11  2019-02-02  42  
12  2019-02-03  34  
13  2019-02-04  35  
14  2019-02-05  21  
15  2019-02-06  31  
16              163 #Formula of SUM for the 5 values
17          
18              741 #Formula of the difference between the two totals

所以我认为第一步是找到一种将公式应用于 csv 文件的方法

所以我需要在我所拥有的基础上再接再厉,也许 awk 的某些东西不知道如何进行,老实说在这方面是全新的。

请保持简单。

谢谢

【问题讨论】:

  • 忘记 XLSX 的命令行工具。与使用 CSV 相比,这是可能的,但不必要地复杂。所以不需要在你的问题中提到 XLSX。您显然已经知道如何将数据库导出为 CSV,因此也无需提及该部分。一旦有了工具,您就可以轻松地弄清楚如何从 cron 调用某些工具,因此这里也无需提及 cron。因此,您的问题归结为如何以某种方式更新 CSV。 edit 您的问题是为了展示简洁、可测试的样本输入和预期输出,以及您尝试这样做 THAT 以便我们为您提供帮助。
  • 谢谢 Ed,将在接下来的几个小时内这样做。感谢您花时间回复我的问题。
  • 请添加示例输入 CSV 文件和输出示例。谢谢
  • 您实际上是在尝试将公式存储在 csv 文件中,还是只是应用公式的结果?
  • 任何一种方式都可以,只要它具有相同的效果,即在更新的 csv 文件上为相同的单元格应用公式,但我认为存储公式会更方便。

标签: bash shell csv awk cat


【解决方案1】:

你可以使用 csvkit https://csvkit.readthedocs.io/en/latest/scripts/csvsql.html

$ cat one.csv
2019-02-01,100
2019-02-02,131
2019-02-03,222
2019-02-04,180
2019-02-05,213

$ cat two.csv
2019-02-01,23
2019-02-02,42
2019-02-03,34
2019-02-04,35
2019-02-05,21

你可以跑

#!/bin/bash

# add header
sed -i  '1s/^/data,value\n/' one.csv
sed -i  '1s/^/data,value\n/' two.csv

one=$(csvsql --query "select sum(value) as sumOne from one" one.csv | tail -n +2)

two=$(csvsql --query "select sum(value) as sumOne from two" two.csv | tail -n +2)

echo "$one-$two" | bc

拥有691

【讨论】:

  • 我遇到的问题是 csv 文件没有命名的列,所以我得到: UnnamedColumnWarning: Column 1 has no name。使用“b”
  • 嗨 @CristianTrandafir 我已经编辑了脚本以从无标题 CSV 文件开始