BASH根据列值将CSV拆分为多个文件



我有一个名为fulldata.tmp的文件,其中包含管道分隔的数据(如果需要,我可以将其更改为逗号,但通常类似于使用管道(。使用BASH Shell脚本,我希望根据第1列中的值将行拆分为新文件,并保留标题。我通过SQL提取这些数据,以便在需要时进行预排序,但我无法直接访问运行此脚本的终端,因此开发和调试很困难。我搜索了几十个主要推荐awk的例子,但我并没有把它们联系起来。这是我的核心需求,下面是我想要的几个生活质量选项,如果简单的话,再加上示例数据。

如果可能的话,这很好:我想指定哪些列打印到新文件中(我想要的输出示例显示,我想要最初5列中的1-4列(。

如果可能的话,这很好:我希望用前缀命名的新文件,然后是要拆分的数据,然后是扩展名:final_$col1.csv

GROUPID|LABEL|DATE|ACTIVE|COMMENT
ABC|001|2022-09-15|True|None
DEF|001|2022-09-16|False|None
GHI|002|2022-10-17|True|Future

final_ABC.csv

ABC|001|2022-09-15|True

final_DEF.csv

DEF|001|2022-09-16|False

final_GHI.csv

GHI|002|2022-10-17|True

也许是awk

awk -F'|' -v OFS='|' 'NR>1{print $1, $2, $3, $4 > "final_"$1".csv"}' fulldata.tmp

检查创建的csv文件及其内容。

tail -n+1 final*.csv 

输出

==> final_ABC.csv <==
ABC|001|2022-09-15|True
==> final_DEF.csv <==
DEF|001|2022-09-16|False
==> final_GHI.csv <==
GHI|002|2022-10-17|True

以下是我如何处理标题。

IFS= read -r head < fulldata.tmp

然后使用变量awk

awk -F'|' -v header="${head%|*}" 'NR>1{printf "%sn%s|%s|%s|%sn", header, $1, $2, $3, $4 > "final_"$1".csv"}' fulldata.tmp

再次运行tail进行检查。

tail -n+1 final*.csv

输出

==> final_ABC.csv <==
GROUPID|LABEL|DATE|ACTIVE
ABC|001|2022-09-15|True
==> final_DEF.csv <==
GROUPID|LABEL|DATE|ACTIVE
DEF|001|2022-09-16|False
==> final_GHI.csv <==
GROUPID|LABEL|DATE|ACTIVE
GHI|002|2022-10-17|True

您确实找到了含有纯awk的溶液。

这样可以工作并保留我认为是必需的头。

cut -d '|' -f 1 fulldata.tmp | grep -v GROUPID | sort -u | while read -r id; do grep -E "^${id}|^GROUPID" fulldata.tmp > final_${id}.csv; done

我认为纯awk解决方案更好。

最新更新