当第一列发现整数时将 csv 文件拆分为较小的文件

当第一列发现整数时将 csv 文件拆分为较小的文件

我有一个如下所示的 csv 文件:

1,'someval','otherval',,,,,
'','someotherval','some_otherval',,,,,
1BSD,'',,,,,
2,'val',,,,,
,,,,,,
2BSD,,,,,,
2BCD,,,,,,

现在,每当新行的第一列是整数值时,我就想要拆分文件。

因此,对于上述 csv 输入,我必须获取 2 个包含以下内容的新文件:

1,'someval','otherval',,,,,
,'someotherval','some_otherval',,,,,
1BSD,'val',,,,,

2,'val',,,,,
,,,,,,
2BSD,,,,,,
2BCD,,,,,,

分别。

如何使用 Bash 和/或 Python 实现此目的?谢谢。

答案1

您可以使用该csplit实用程序按正则表达式进行拆分,例如

csplit -z file.csv '/^[0-9]\+,/' '{*}'
80
42

(计数表示输出到每个文件的字符数 - 您可以通过添加选项来抑制它们-s)。

输出文件默认命名xx00xx01等 - 如果您愿意,可以选择更改前缀和后缀。

前任。

$ csplit -z file.csv '/^[0-9]\+,/' '{*}'
80
42
$ head xx*
==> xx00 <==
1,'someval','otherval',,,,,
'','someotherval','some_otherval',,,,,
1BSD,'',,,,,

==> xx01 <==
2,'val',,,,,
,,,,,,
2BSD,,,,,,
2BCD,,,,,,

答案2

我想看看我能用 做多少这样的事情sed,而且我确实做到了相当多。我们可以sed使用wW命令写入文件,但我想不出在sed循环的每次迭代中写入不同文件的方法,所以我不得不使用 shell 循环。sed可能不是适合这项工作的工具,使用 可能有更好的方法sed。无论如何,这就是我想出的办法:

#!/bin/bash
sed ':a;N;s/\n/\x00/; ta' input | sed -r 's/\x00([0-9]+(,|\x00|$))/\n\1/g' > edited
n=0
while [ -s edited ]; do 
    ((n++))
    sed -n '1p' edited > csv-"$n"
    sed -i '1d' edited
done
sed -i 'y/\x00/\n/' csv-*
rm edited

评论

  • \x00使用循环将换行符替换为空字符sed。这样我们以后就可以使用换行符作为有意义的分隔符。

    sed ':a;N;s/\n/\x00/; ta' input
    
  • 通过管道传输结果并在第一个字段的整数前添加换行符,然后将结果写入文件,edited

    | sed -r 's/\x00([0-9]+(,|\x00|$))/\n\1/g' > edited
    
  • 初始化变量以增加

    n=0
    
  • 只要edited不空,做事

    while [ -s edited ]; do
    
  • 增量n

    ((n++))
    
  • 将 的第一行写入edited新文件csv-$n,其中$n是 的当前值n

    sed -n '1p' edited > csv-"$n"
    
  • 删除第一行edited

    sed -i '1d' edited
    

    这是循环的结束,因为我们要写入的每个文件只有一行,所以这并不像在循环中处理原始文件的每一行那么慢,但仍然很慢!

  • 对于我们创建的每个文件,将空字符重新转换为换行符

    sed -i 'y/\x00/\n/' csv-*
    
  • 删除中间文件

    rm edited
    

相关内容