标题: [问题求助] PowerShell怎样将csv中大致重复的项另存为新csv文件 [打印本页]
作者: 5i365 时间: 2022-1-6 18:42 标题: PowerShell怎样将csv中大致重复的项另存为新csv文件
如何用powershell将csv文件中大致重复的项另存为新csv文件,
例如下面的这个csv文件, 歌手和歌名并非完全重复
------------------------------------------------------------------------------
排序,语言,歌手,歌名
66,国语,安静,红颜知己
67,国语,韩可可,错位时空 (女版)
68,国语,于洋,望爱却步
75,国语,胡小斐,无药可愈
76,国语,en,嚣张
565,国语,韩可可(3),错位时空
566,国语,杜宣达,原来我从未忘记你
567,国语,悦开心,别想他
568,国语,新乐尘符,123我爱你
作者: 5i365 时间: 2022-1-7 12:25
这个有解吗? 一点头绪也没有
作者: went 时间: 2022-1-7 13:05
只根据括号内容(.*?)区分就很简单
输入0.csv 输出1.csv- #&cls&@ cd /d "%~dp0" & powershell -c "Get-Content '%~0' | Out-String | Invoke-Expression" & pause&exit
- $set = @{}
- $content = Get-Content '0.csv' -Encoding UTF8
- $content | foreach {
- $arr = $_ -split ','
- $a = ($arr[2] -replace '\(.*?\)','').Trim() + ',' + ($arr[3] -replace '\(.*?\)','').Trim()
- if($set.$a -eq $null){
- $set.$a = $_
- } else {
- $set.$a = $set.$a + "`n" + $_
- }
- }
-
- $set.Values | Where-Object { ($_ -split '\n').Count -gt 1 } | Out-File '1.csv'
复制代码
作者: 5i365 时间: 2022-1-7 13:38
本帖最后由 5i365 于 2022-1-7 13:44 编辑
回复 3# went
感谢帮忙, 我现在想了一个逻辑,
如果歌手中有连续的三个字重复【即csv文件第三行】, 同时歌名中有连续的三个字重复【即csv文件第四行】, 此时就算满足条件, 最好有个变量, 我可以修改连续文字的数量
还有个可能的情况是,不只两行中的有重复的情况, 还有可能是三行或N行中有上面描述的重复情况
作者: went 时间: 2022-1-7 14:10
回复 4# 5i365
没有测试大量数据- cls
- #函数 获取两个字符串最大相同字符个数
- function Get-SameNum([string]$str1,[string]$str2){
- $max = 0
- $len = 0
- if($str1.Length -le $str2.Length){
- $len = $str1.Length
- $s1 = $str1
- $s2 = $str2
- } else {
- $len = $str2.Length
- $s1 = $str2
- $s2 = $str1
- }
- for($i = 0;$i -lt $len; $i++){
- for($j = 1; $j -lt $len-$i+1; $j++){
- $s_t = $s1.Substring($i,$j)
- if($s2.IndexOf($s_t) -ne -1){
- if($s_t.Length -gt $max){
- $max = $s_t.Length
- }
- }
- }
- }
- return $max
- }
-
- #阈值设置 >=
- $m1 = 3
- $m2 = 3
- #比较并输出
- $content = Get-Content '0.csv' -Encoding UTF8
- &{
- $content | foreach {
- $__ = $_
- $content | Where-Object { $_ -ne $__} | foreach {
- $arr1 = $__ -split ','
- $arr2 = $_ -split ','
- $a = Get-SameNum -str1 $arr1[2] -str2 $arr2[2]
- $b = Get-SameNum -str1 $arr1[3] -str2 $arr2[3]
- if($a -ge $m1 -and $b -ge $m2){
- $__
- }
- }
- }
- } | Out-File '1.csv'
复制代码
作者: 5i365 时间: 2022-1-7 18:52
回复 6# xczxczxcz
感谢分享, 执行后,生成的文件为空, 请问如何使用?
作者: 5i365 时间: 2022-1-7 19:02
本帖最后由 5i365 于 2022-1-7 19:11 编辑
回复 5# went
如果csv有1000条,不知是对比时间太漫长还是怎么一直不能结束, 然后我就手动关闭了,生成的结果中,还是有问题,相同的并没有上下显示在相邻行
作者: xczxczxcz 时间: 2022-1-7 19:54
回复 7# 5i365
不会用那就不用,你还是使用低效版吧。
实测上万条数据也就弹指一挥间完成,稍为改一下就是高效率了。
禁止套娃。
作者: went 时间: 2022-1-7 20:29
回复 7# 5i365
可以传csv附件给我测试优化
作者: 5i365 时间: 2022-1-8 09:42
本帖最后由 5i365 于 2022-1-8 09:51 编辑
回复 8# xczxczxcz
大侠, 侠气凛然, 着实让从人佩服!!!
在下不才, 昨晚真是试了很多次没有结果, 到头了没看懂你写的怎么用,
论坛本来就是个学习的地方, 但凡路过的坛友, 学习一翻你的代码, 更显你的豪气, 更多一份敬佩!!
但是刚才一找, 代码删了, 不见了, 那真就是在俺一个入门者面前耍一下大刀, 炫技了一翻, 没有任何意义
无论如何, 大侠能抽自己的时间和精力加入到处理这个论坛问题的队伍中来, 还是非常感谢的
不明白什么叫 禁止套娃, 百度了一下刚懂, 现在娃没有了, 是不是大家可以随便套了?
作者: 5i365 时间: 2022-1-8 10:04
回复 9# went
感谢回复, 已传, 大侠认真的态度让人钦佩, 宛若论坛中的一股清流!
作者: went 时间: 2022-1-8 13:04
本帖最后由 went 于 2022-1-8 13:09 编辑
回复 11# 5i365
还是 输入0.csv 输出1.csv- #&cls&@powershell -c "Get-Content '%~0' | Select-Object -Skip 1 | Out-String | Invoke-Expression" &pause&exit
- cls
- #函数 获取两个字符串最大相同字符个数
- function Get-SameNum([string]$str1,[string]$str2){
- $max = $len = 0
- if($str1.Length -le $str2.Length){
- $len = $str1.Length; $s1 = $str1; $s2 = $str2
- } else {
- $len = $str2.Length; $s1 = $str2; $s2 = $str1
- }
- for($i = 0;$i -lt $len; $i++){
- if($len-$i -le $max){ break; }
- for($j = 1; $j -lt $len-$i+1; $j++){
- $s_t = $s1.Substring($i,$j)
- if($s2.IndexOf($s_t) -ne -1){
- if($s_t.Length -gt $max){ $max = $s_t.Length }
- }
- }
- }
- return $max
- }
-
- #阈值设置 >=
- $m1 = 3
- $m2 = 3
- #比较并输出
- $list = [System.Collections.ArrayList](Get-Content '0.csv' -Encoding UTF8 | Select-Object -Skip 1)
- &{
- &{
- $list | Sort-Object {
- $arr = $_ -split ','
- ($arr[2] -replace '[\(\[\{].*[\)\]\}]',''),
- ($arr[3] -replace '[\(\[\{].*[\)\]\}]',''),
- ($arr[0])
- } | foreach {
- $line = $_
- $singer = ($_ -split ',')[2]
- $song = ($_ -split ',')[3]
- if($last_line -ne $null){
- $a = Get-SameNum -str1 $singer -str2 $last_singer
- if($a -ge $m1){
- $b = Get-SameNum -str1 $song -str2 $last_song
- if($b -ge $m2){
- if(!$last){ $last_line; $last = $true}
- $_
- }
- } else {
- $last = $false
- }
- }
- $last_line = $line
- $last_singer = $singer
- $last_song = $song
- }
- }
- } | Out-File '1.csv'
复制代码
作者: 5i365 时间: 2022-1-8 13:51
回复 12# went
感谢, 刚才试了一下, 得到下面的结果:
但有些项不应输出,例如;
795和534, 562和578, 851和501, 都是两首歌, 是同一歌手唱
前两组的输出是对的
感觉现在对比的逻辑是: 要先排除歌名中的括号中的内容后再对比
------------------------------------------------------
546,国语,Bomb比尔,0222心动-比尔的歌
407,国语,Bomb比尔,1022-比尔的歌
67,国语,韩可可,错位时空 (女版)
565,国语,韩可可(3),错位时空
795,粤语,亮声open,多年以后 (粤语版)
534,粤语,亮声open,无人与我 (粤语版)
562,国语,刘大壮,我很好 (吉他版)
578,国语,刘大壮,一吻天荒 (吉他版)
851,国语,杨冰心,红尘谁不是过客 (女版)
501,国语,杨冰心,学会爱自己 (女版)
作者: went 时间: 2022-1-8 14:17
回复 13# 5i365
37.38行修改下- $singer = ($_ -split ',')[2] -replace '[\(\[\{].*[\)\]\}]',''
- $song = ($_ -split ',')[3] -replace '[\(\[\{].*[\)\]\}]',''
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |