标题: [问题求助] PowerShell提取txt中的数字后对比csv中的序号所在列,然后导出新csv文件 [打印本页]
作者: 5i365 时间: 2022-1-1 12:32 标题: PowerShell提取txt中的数字后对比csv中的序号所在列,然后导出新csv文件
遇到一个新的问题, 期待高手能帮忙, 提前感谢!
具体描述如下:
1.有一个名为A.csv文件内容如下:
序号,语言,歌手,歌名
1,国语,付雪,金玉良缘
2,国语,阿吉太组合,阿衣莫
3,国语,洛先生,孤城
4,国语,刘艺雯,听闻远方有你
5,国语,海来阿木,五十年以后
6,国语,海来阿木,浮生记
7,国语,杨小壮,最后的人
8,国语,莫叫姐姐,你能不能不要离开我 (莫叫语版)
9,国语,郁可唯,路过人间
2.有一个主文件夹B 其下包含很多文件和子文件夹
3.在B下的有些txt文件的文件名中, 可能包含文字 【歌手】 或 【歌名】
4.只关注文件名包含 【歌手】 或 【歌名】 文字的txt文件, 其内容中,某行可能包含某个数字,只关注1位至4位的数字
需要:
A.csv文件的序号这一列, 如果包含上面提到的1位或4位数字, 则将该序号所在的行, 另存到C.csv文件中
需要注意的是:
有些数字可能会重复,那就只算一个
C.csv文件中首行要有A.csv文件的首行标题
C.csv文件中的第二行至结尾行按第一行的序号升序排列
作者: 5i365 时间: 2022-1-2 11:58
本帖最后由 5i365 于 2022-1-2 12:05 编辑
看到一篇文章, 说是用select-string 这个命令可以不打开文件就能搜索文本,
但是上面又涉及到了读写csv,还有排序, 搜索文件夹, 搜索文件名等,知识点有点多, 吃不消, 搞不出来, 期待路过高手帮忙一下
作者: idwma 时间: 2022-1-2 14:34
本帖最后由 idwma 于 2022-1-2 17:42 编辑
万能的正则- $a=@{}
- type a.csv|%{
- $z=$_ -replace '^(\d+).*','$1'
- if (!($a.ContainsKey($z))){$a.$z=$_}
- }
- $b=@{}
- dir -recu b\* -inc *歌手*.txt,*歌名*.txt|%{
- foreach($i in (type $_) -match '\d+'){
- $z=$i -replace '\D*(\d+)\D*','$1'
- if(!($b.ContainsKey($z))){$b.$z=$a.$z}
- }
- }
- $b.Values|sort{"{0:d5}" -f [int]($_ -replace '^(\d+)\D*','$1')}
复制代码
作者: 5i365 时间: 2022-1-2 19:00
本帖最后由 5i365 于 2022-1-2 19:05 编辑
回复 3# idwma
感谢帮助, 加了.\ 然后试了一下, 回显乱码, 没生成C.csv
#@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
$a=@{}
type .\a.csv|%{
$z=$_ -replace '^(\d+).*','$1'
if (!($a.ContainsKey($z))){$a.$z=$_}
}
$b=@{}
dir -recu .\b\* -inc *歌手*.txt,*歌名*.txt|%{
foreach($i in (type $_) -match '\d+'){
$z=$i -replace '\D*(\d+)\D*','$1'
if(!($b.ContainsKey($z))){$b.$z=$a.$z}
}
}
$b.Values|sort{"{0:d5}" -f [int]($_ -replace '^(\d+)\D*','$1')}
测试文件
https://wss1.cn/f/79ly70c7tnk 复制链接到浏览器打开
作者: idwma 时间: 2022-1-2 19:33
回复 4# 5i365 - $a=@{}
- $f=[io.file]::ReadAllLines('.\a.csv')
- $f|%{
- $z=$_ -replace '^(\d+).*','$1'
- if (!($a.ContainsKey($z))){$a.$z=$_}
- }
- $b=@{}
- dir -recu * -inc *歌手*.txt,*歌名*.txt,*歌曲*.txt|%{
- foreach($i in [io.file]::ReadAllLines($_) -match '\d+'){
- $z=$i -replace '\D*(\d+)\D*','$1'
- if(!($b.ContainsKey($z))){$b.$z=$a.$z}
- }
- }
- sc b.csv ($f[0],($b.Values|sort{[int]($_ -replace '^(\d+)\D*','$1')}))
复制代码
作者: 5i365 时间: 2022-1-2 19:40
回复 5# idwma
再请教一下, 4楼的批处理,需要保存成什么编码格式? asci 还是 utf8
我对这两个编码一直不理解, 一个不行我就转另一个, 没有头绪,
如何用第一行的代码也就下面这行自动把ps转码? 这样不管我存成什么编码都可以执行了
#@&cls&powershell "type '%~0'|out-string|iex"&pause&exit
作者: idwma 时间: 2022-1-2 19:53
本帖最后由 idwma 于 2022-1-2 19:55 编辑
回复 6# 5i365
一直用默认的ansi,太清楚有什么不同
好像utf8也可以运行
作者: 5i365 时间: 2022-1-2 19:58
回复 7# idwma
好像powershell用utf8可以, 但有时也不行, 我是用的 notepad2 编辑文本的
作者: 5i365 时间: 2022-1-6 10:04
回复 5# idwma
出了点问题, 这也是我为什么不太爱使用正则的原因, 要考虑很多情况,
下面是示例文件
https://wss1.cn/f/7an8a3ux7fk 复制链接到浏览器打开
会提示下面的错误,导出的csv也没有按顺序排列
----------------------------------------------------------
sort : Cannot convert value "13297、周思涵,感谢你曾来过" to type "System.Int32". Error: "Input string was not in a corr
ect format."
At line:15 char:30
+ ... v ($f[0],($b.Values|sort{[int]($_ -replace '^(\d+)\D*','$1')})) -Enco ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidResult: (132,国语,Ayo97、周思涵,感谢你曾来过SObject) [Sort-Object], RuntimeExcep
tion
+ FullyQualifiedErrorId : ExpressionEvaluation,Microsoft.PowerShell.Commands.SortObjectCommand
请按任意键继续. . .
作者: qixiaobin0715 时间: 2022-1-6 12:32
用批处理也行:- @echo off
- chcp 65001>nul
- setlocal enabledelayedexpansion
- pushd "任务"
- for /f "delims=" %%i in ('dir /b /s /a-d *伴奏*.txt *歌词*.txt *原唱*.txt') do (
- for /f "delims=" %%j in (%%i) do (
- set n=%%j
- set /a n=n
- set m=000!n!
- set _!m:~-4!=!n!
- )
- )
- popd
- for /f "tokens=2 delims==" %%a in ('set _') do set k=!k!%%a,
- findstr /b /r "!k!" 0-1001.csv>b.csv
- pause
复制代码
作者: idwma 时间: 2022-1-6 15:45
回复 9# 5i365
排序部分还可以用went教的方法- $b.Values|sort{[int]($_ -split ',')[0]}
复制代码
作者: 5i365 时间: 2022-1-12 11:09
回复 5# idwma
大侠, 我想在提取某个txt中的数字后, 把该txt里面的内容清空, 可以实现吗?
注意要点:
1.如果一个txt中没有数字, 那不能清空里面的内容, 因为没有提取里面的数字
2.如果一个txt中虽然有数字, 但是不在csv的第一列当中, 那也不能清空里面的内容
作者: idwma 时间: 2022-1-12 14:08
回复 12# 5i365 - $a=@{}
- $f=[io.file]::ReadAllLines('.\a.csv')
- $f|%{
- $z=$_ -replace '^(\d+).*','$1'
- if (!($a.ContainsKey($z))){$a.$z=$_}
- }
- $b=@{}
- dir -recu * -inc *歌手*.txt,*歌名*.txt,*歌曲*.txt|%{
- foreach($i in [io.file]::ReadAllLines($_) -match '\d+'){
- $z=$i -replace '\D*(\d+)\D*','$1'
- if(!($b.ContainsKey($z))){$b.$z=$a.$z}
- }
- if($b.ContainsKey($z)){sc $_ ''}
- }
- sc b.csv ($f[0],($b.Values|sort{[int]($_ -split ',')[0]}))
复制代码
作者: 5i365 时间: 2022-1-12 15:32
回复 13# idwma
没有清空 那些文件, 生成的b.csv里只有标头
作者: idwma 时间: 2022-1-12 15:54
回复 14# 5i365
文件链接过期了再发一个来看看
作者: 5i365 时间: 2022-1-12 16:26
回复 15# idwma
好的, 多谢, 另外目前代码中 下面这行代码, 是搜索所有的这些txt文件中的数字,对比a.csv的第一列的数字后,然后输出一个b.csv, 我现在想: 包含*原唱*.txt中的文件夹中的数字对比a.csv的第一列的数字后,输出为 原唱.csv, 包含*伴奏*.txt中的文件夹中的数字对比a.csv的第一列的数字后,输出为 伴奏.csv, 包含*歌词*.txt中的文件夹中的数字对比a.csv的第一列的数字后,输出为 歌词.csv
dir -recu * -inc *原唱*.txt,*伴奏*.txt,*歌词*.txt
https://wss1.cn/f/7cfkwglj3kw 复制链接到浏览器打开
作者: idwma 时间: 2022-1-12 18:30
回复 16# 5i365 - #@&cls&powershell -version 2.0 "type '%~0'|out-string|iex"&pause&exit
- $a=@{}
- $f=gc a.csv
- $f|%{
- $z=$_ -replace '^(\d+).*','$1'
- if (!($a.ContainsKey($z))){$a.$z=$_}
- }
- $b=@{}
- $d=@{}
- dir -recu * -inc *原唱*.txt,*伴奏*.txt,*歌词*.txt|%{
- if($_ -match '(原唱|伴奏|歌词)'){$c=$Matches[0]}
- foreach($i in gc $_){
- if($i -match '\d'){
- $z=$i -replace '\D*(\d+)\D*','$1'
- if(!($b.ContainsKey($z))){$b.$z=$a.$z;$d.$c+=@($a.$z)}
- }
- }
- if($b.ContainsKey($z)){sc $_ ''}
- $z=-1
- }
- $d.keys|%{sc $($_+'.csv') ($f[0],($d.$_|sort{[int]($_ -split ',')[0]}))}
复制代码
作者: 5i365 时间: 2022-1-13 14:55
回复 17# idwma
大侠, 刚刚在WIN10上运行直接提示 让装相对应的.net, 应该是 第一行的 限定版本导致的, 而win10上没有.net 2
我把版本号删了, 运行不成功, 也报错, 以前的那个批处理 就不用限定PS版本, 只是把所有的数字都输出到一个b.csv中了
作者: idwma 时间: 2022-1-13 15:54
回复 18# 5i365
开win10试了一下自带的5.1也可以的
作者: 5i365 时间: 2022-1-13 18:38
本帖最后由 5i365 于 2022-1-13 18:39 编辑
回复 19# idwma
在我的那个压缩包里面的示例执行, 把版本删了可以执行, 但是我改了一下dir路径, 和过滤的文件名的文字, 执行就出错了, 多亏有备份, 因为有些txt文件会被清空
如果不清空原txt, 只导出独立的文本, 需要注释哪行代码?
作者: idwma 时间: 2022-1-13 19:11
回复 20# 5i365
18
19
作者: 5i365 时间: 2022-1-21 10:53
本帖最后由 5i365 于 2022-1-21 19:07 编辑
回复 21# idwma
您好, 现在有两个问题想请教
1.有时获取的.txt文件中,例如下面的示例, 数字并不全是在开头, 而是在一行的中间[如下面的32]或结尾[如下面的28], 怎样设置三个筛选开关分别对应三种情况? 例如, 我只想筛选结尾的数字时就将其开关打开
--------------------------------------------------------------------
58有问题
80伴奏有问题 需要重新下载正确的
正确的32, 错误的28
132没有伴奏
2.txt文件, 可能在不同的文件夹中, 想在导出的csv文件名前,加上其所在的文件夹名
例如导出的 歌词.csv 文件, 他是筛选的 1号 文件夹下的, 名字就改为 1号_歌词.csv
--------------------------------------------------------------------------------------------------------------------------------------
要修改的代码, 及文件 https://send.cm/d/84IN- #@&cls&powershell -version 2.0 "type '%~0'|out-string|iex"&pause&exit
- $a=@{}
- $f=gc 歌单.csv -Encoding UTF8
- $f|%{
- $z=$_ -replace '^(\d+).*','$1'
- if (!($a.ContainsKey($z))){$a.$z=$_}
- }
- $b=@{}
- $d=@{}
- dir ".\任务" -recu * -inc *原唱*.txt,*伴奏*.txt,*歌词*.txt|%{
- if($_ -match '(原唱|伴奏|歌词)'){$c=$Matches[0]}
- foreach($i in gc $_){
- if($i -match '\d'){
- $z=$i -replace '\D*(\d+)\D*','$1'
- if(!($b.ContainsKey($z))){$b.$z=$a.$z;$d.$c+=@($a.$z)}
- }
- }
- #if($b.ContainsKey($z)){sc $_ ''} #清空
- #$z=-1 #清空
- }
- $d.keys|%{sc -Encoding UTF8 $($_+'.csv') ($f[0],($d.$_|sort{[int]($_ -split ',')[0]}))}
复制代码
作者: idwma 时间: 2022-1-21 15:17
回复 22# 5i365 - #@&cls&powershell -version 2.0 "type '%~0'|out-string|iex"&pause&exit
- $r='^(\d+).+' #1
- #$r='\D+(\d+)\D+' #2
- #$r='\D+(\d+)$' #3
-
- $a=@{}
- $f=gc 歌单.csv -Encoding UTF8
- $f|%{
- $z=$_ -replace '^(\d+).*','$1'
- if (!($a.ContainsKey($z))){$a.$z=$_}
- }
- $b=@{}
- $d=@{}
- dir ".\任务" -recu * -inc *原唱*.txt,*伴奏*.txt,*歌词*.txt|%{
- if($_ -match '(原唱|伴奏|歌词)'){$c=$Matches[0]}
- foreach($i in gc $_){
- if($i -match '\d'){
- $z=$i -replace $r,'$1'
- if(!($b.ContainsKey($z))){$b.$z=$a.$z;$d.$c+=@($a.$z)}
- }
- }
- #if($b.ContainsKey($z)){sc $_ ''} #清空
- #$z=-1 #清空
- }
- $d.keys|%{sc -Encoding UTF8 $($_+'.csv') ($f[0],($d.$_|sort{[int]($_ -split ',')[0]}))}
复制代码
作者: 5i365 时间: 2022-1-21 19:07
本帖最后由 5i365 于 2022-1-21 19:09 编辑
回复 23# idwma
刚试了一下, 第一条OK了, 下面这条没有
txt文件, 可能在不同的文件夹中, 想在导出的csv文件名前,加上其所在的文件夹名
例如导出的 歌词.csv 文件, 他是筛选的 1号 文件夹下的, 名字就改为 1号_歌词.csv
示例中, 有 1号 和 2号 两个文件夹,
1号 中提取其下txt中的数字后, 生成的csv文件, 带上前缀 1号_
2号 中提取其下txt中的数字后, 生成的csv文件, 带上前缀 2号_
作者: idwma 时间: 2022-1-21 20:32
本帖最后由 idwma 于 2022-1-22 00:13 编辑
回复 24# 5i365 - #@&cls&powershell -version 2.0 "type '%~0'|out-string|iex"&pause&exit
- #$r='^(\d+).*' #1
- $r='^\D+(\d+)\D' #2
- #$r='\D+(\d+)$' #3
-
- $a=@{}
- $f=gc 歌单.csv -Encoding UTF8
- $f|%{
- $z=$_ -replace '^(\d+).*','$1'
- if (!($a.ContainsKey($z))){$a.$z=$_}
- }
- $d=@{}
- dir ".\任务" -recu * -inc *原唱*.txt,*伴奏*.txt,*歌词*.txt|%{
- if($_ -match '(原唱|伴奏|歌词)'){$c=$($_.fullname -replace '^.*?([^\\]*)\\[^\\]*$','$1')+'_'+$Matches[0]}
- foreach($i in gc $_){
- if($i -match $r){
- $z=$matches[1]
- if($a.ContainsKey($z)){$d[$c]+=@($a.$z)}
- }
- }
- }
- $d.keys|%{sc -Encoding UTF8 $($_+'.csv') ($f[0],($d.$_|sort{[int]($_ -split ',')[0]}))}
复制代码
作者: 5i365 时间: 2022-1-22 06:54
回复 26# 5i365
23楼的, 22,23行清空已筛选的的txt文件代码, 加在哪里?
作者: idwma 时间: 2022-1-22 13:36
回复 26# 5i365
$b改成$a还是放在原来的地方
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |