根据字段值将一个CSV文件拆分成多个文件

3

I do have a CSV which looks like this*:

system,subject,value1,value2
example.org,thing 1,100,4
exmaple.org,thing 2,90,0
example.com,thing 1,200,0
example.com,thing 5,10,10

实际上,标题并未包含在内,但在此处显示以使示例更易于阅读。

而我想将其分成两个文件:

example.org.csv 包含:

thing 1,100,4
thing 2,90,0

使用example.com.csv文件:

thing 1,200,0
thing 5,10,10

我的当前解决方案是这样的:

while read line; do
  SYSTEM=$(echo "$line" | cut -d, -f1)
  NOTTHESYSTEM=$(echo "$line" | cut -d, -f2-)
  echo "${NOTTHESYSTEM}" >> "${SYSTEM}.csv"
done <$INPUT

但是这种方法效率非常低,并且在处理大文件时性能表现不佳。
具体来说,一个包含52050行/ 9MB的文件需要约250秒才能完成分割。
欢迎提出任何改进上述脚本的建议。
祝好
2个回答

4

使用 awk 将更加简单:

awk 'BEGIN{FS=OFS=","} {print $2, $3, $4 > $1 ".csv"}' "$INPUT"

验证:

cat example.org.csv
thing 1,100,4
thing 2,90,0

cat example.com.csv
thing 1,200,0
thing 5,10,10

1
非常快 - 谢谢。现在运行时间只有0.3秒,而不是250秒。 - pagid
能否使用这种方法添加gzip阶段,以便所有输出文件都被压缩成gzip格式? - Sahas
只需将输出重定向到一个文件中,然后调用 gzip 压缩它。 - anubhava

1
假设您的系统数量较少,有一种方法可以实现它:
cut -d, -f1 file.csv | \
    sort -u | \
    while read -r system; do
        fgrep -w "$system" file.csv | cut -d, -f2- >"$system".csv
    done

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接