Board logo

标题: [问题求助] 如何用powershell将一个csv文件平均分成N份并保留标题头 [打印本页]

作者: 5i365    时间: 2021-12-17 12:33     标题: 如何用powershell将一个csv文件平均分成N份并保留标题头

本帖最后由 5i365 于 2021-12-17 21:15 编辑

遇到一个csv文件, 太长了, 想把它平均分成N份并保留标题头, 新文件名在原文件名基础上加序号
这里有个不能平均等分的情况: 例如下面的例子, 歌曲只有9首, 平均分成4份, 那最后一首歌就存到一个文件
百度了一些资料, 看了下都是翻译的国外的, 看不太懂, 请求高手支招

CSV文件内容如下:

排序,语言,歌手,歌名
1,国语,付雪,金玉良缘
2,国语,阿吉太组合,阿衣莫
3,国语,洛先生,孤城
4,国语,刘艺雯,听闻远方有你
5,国语,海来阿木,五十年以后
6,国语,海来阿木,浮生记
7,国语,杨小壮,最后的人
8,国语,莫叫姐姐,你能不能不要离开我 (莫叫语版)
9,国语,郁可唯,路过人间

作者: 5i365    时间: 2021-12-18 07:19

本帖最后由 5i365 于 2021-12-18 07:24 编辑

在国外找到一个工具,简直就是为我量身定制的, 太牛B了, 分享给大家

下载链接
https://www.erdconcepts.com/dbtoolbox/csvsplitter/csvsplitter.zip
作者: 5i365    时间: 2021-12-18 07:23

另外在国外so上找到一个用sed的方法, 代码只有4行, 但是不知道sed在哪里下载, 也不知道那个option选项怎么设置, 期待高手能解释一下, 多谢, 代码如下:

header=$(head -1 $file)
data=$(tail -n +2 $file)

echo $data | split [options...] -
在选项中,您必须指定块的大小以及结果文件名的模式。尾随-不能删除,因为它指定从stdin读取数据。

然后可以在每个文件的顶部插入头
sed -i "1i$header" $splitOutputFile
作者: qixiaobin0715    时间: 2021-12-18 09:49

大部分文本编辑器都有这种功能啊,比如EmEditor可按行或书签分割文本,分割后的文件名可定制,速度秒杀。
作者: idwma    时间: 2021-12-18 19:10

  1. $d="abc.csv"
  2. $a=type $d
  3. $b=4
  4. [int]$c=$a.count/$b
  5. for($i=1;$i -lt $a.count;$i+=$c){
  6. sc ("{0}-{1:d3}.txt" -f $d,$f++) ($a[0],$a[$i..($i+$c-1)])
  7. }
复制代码

作者: Batcher    时间: 2021-12-18 19:34

回复 3# 5i365


sed命令可以从这里下载:
http://bcn.bathome.net/s/tool/index.html?key=sed

不过你找到的这几行代码是Linux Shell脚本,无法直接在Windows里面直接执行。
作者: 5i365    时间: 2021-12-18 19:56

回复 5# idwma

感谢大侠帮忙, 话说真是比上面的软件轻巧, 软件要一两M的大小

现在执行后文件名是这样的, abc.csv-000.txt
如何改成abc-000.csv
作者: 5i365    时间: 2021-12-18 20:00

回复 5# idwma


   我在下面这个贴子里,采用了您的第一行cmd代码, 让他执行ps, 貌似,直接在what-if 时显示的结果正确, 但一执行就不行, 不知道为什么
http://www.bathome.net/redirect. ... 1038&pid=249399
作者: 5i365    时间: 2021-12-18 20:07

回复 6# Batcher


    感谢提醒, 我记得以前您在我的别的贴子就提过sed ,代码不能通用吗?
作者: idwma    时间: 2021-12-18 20:16

回复 7# 5i365

what-if这个问题不会呀
  1. $d="abc.csv"
  2. $a=type $d
  3. $b=4
  4. [int]$c=$a.count/$b
  5. for($i=1;$i -lt $a.count;$i+=$c){
  6. sc ("{0}-{1:d3}.{2}" -f ($d -replace '^(.*)\..*','$1'),$f++,($d -replace '^.*\.(.*)$','$1')) ($a[0],$a[$i..($i+$c-1)])
  7. }
复制代码

作者: 5i365    时间: 2021-12-18 20:29

回复 10# idwma


    我懂的太浅了, {}中的代码,一点也看不懂了
作者: Batcher    时间: 2021-12-19 19:45

回复 9# 5i365


    3楼代码是Linux Shell的语法,跟sed是否通用没啥必然联系吧。
作者: 5i365    时间: 2021-12-19 20:26

回复 12# Batcher


    不是有win版吗? win版 没有上面的功能吗? 不是太懂, 所以就问一下
作者: Batcher    时间: 2021-12-19 20:42

回复 13# 5i365


我换个方式试试看:

header=$(head -1 $file)
data=$(tail -n +2 $file)
echo $data | split [options...] -
上面3行是Linux Shell脚本,分割文件主要是Linux split命令的作用。

sed -i "1i$header" $splitOutputFile
sed命令只是在最后一步完成了添加表头的功能,Window里面如果你已经完成了分割文件的操作,也能用类似的sed命令来添加表头。
作者: 5i365    时间: 2021-12-19 20:44

回复 14# Batcher


    多谢解释, 明白了个大概, 感觉还是powershell 好用些
作者: 5i365    时间: 2021-12-21 12:30

回复 5# idwma


   你好, 怎样在均分时把生成的csv文件名的格式改为:  新csv文件内容中的, 第一首歌曲序号-最后一首歌曲序号
# 例如: 分成两份
# 第一个csv文件的名字就是  1-5.csv
# 第二个csv文件的名字就是  6-9.csv

原代码:

#@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
$d="abc.csv"
$a=type $d
$b=2
[int]$c=$a.count/$b
for($i=1;$i -lt $a.count;$i+=$c){
sc ("{0}-{1:d3}.txt" -f $d,$f++) ($a[0],$a[$i..($i+$c-1)])
}

原csv文件内容如下:

排序,语言,歌手,歌名
1,国语,付雪,金玉良缘
2,国语,阿吉太组合,阿衣莫
3,国语,洛先生,孤城
4,国语,刘艺雯,听闻远方有你
5,国语,海来阿木,五十年以后
6,国语,海来阿木,浮生记
7,国语,杨小壮,最后的人
8,国语,莫叫姐姐,你能不能不要离开我 (莫叫语版)
9,国语,郁可唯,路过人间

作者: idwma    时间: 2021-12-21 15:32

回复 16# 5i365
  1. #@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
  2. $d="abc.csv"
  3. $a=type $d
  4. $b=2
  5. [int]$c=$a.count/$b
  6. for($i=1;$i -lt $a.count;$i+=$c){
  7. sc ("{0}-{1}.csv" -f ($a[$i] -replace '^(\d+),.*','$1'),($a[$i..($i+$c-1)][-1] -replace '^(\d+),.*','$1')) ($a[0],$a[$i..($i+$c-1)])
  8. }
复制代码

作者: 5i365    时间: 2021-12-21 18:37

本帖最后由 5i365 于 2021-12-21 18:39 编辑

回复 17# idwma


    后面部分看不太懂, 但大概意思懂, 应该是用替换的方法取值给文件名,

但总是但心, 这种方法不稳, 比如, 文件名中出现了符号, 空格组合什么的,

要是能分解为几步明了的步骤就好多了,
作者: qixiaobin0715    时间: 2021-12-21 19:22

做总是比说来的实在。把想得的特殊字符加入文本中测试即可。
作者: idwma    时间: 2021-12-21 19:52

回复 18# 5i365


很好懂呀,第7行只有3个知识点
格式字符串,正则,数组




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2