Board logo

标题: [文本处理] 批处理怎样把数据流转化成文件? [打印本页]

作者: 304802301    时间: 2024-11-3 19:29     标题: 批处理怎样把数据流转化成文件?

各位论坛大神,有个需求,需要各位大神帮忙处理
1、有一个list.txt,有几万行,每一行数据格式都一致,都是【文件名称.后缀】+@#@+【文件自身经过转换后的数据流】。
2、比如示例中第一行,+@#@+的作用是分隔,前面【word附件dy.doc】是文件名字+格式,后面的一直到第一行末尾,都是文件的数据流。
3、这个文件的数据流,不清楚是怎么编码的。。。原来是正常文件通过转码变成的这个数据流,现在等于是反一下,数据流变成文件了。我是小白,真的搞不懂原来是怎么转码的。。只知道这个数据流肯定可以反转化变成文件的。
4、示例中有3行数据,对应的三个转换后的文件,可供参考,我需要一个bat自动把每一行+@#@+后面的文件数据流自动转换成文件,并重命名为+@#@+前面的文件名称+格式
链接:https://pan.baidu.com/s/1dzTx-jk03_wpC3NXRiE7Ag
提取码:dkfd
作者: Five66    时间: 2024-11-3 23:19

看了下 ,应该是base64编码的数据流
作者: Five66    时间: 2024-11-4 13:38

本帖最后由 Five66 于 2024-11-4 13:58 编辑

保存为ansi编码的bat然后运行
假设base64编码的数据都有填充
  1. @{}#? 2>nul&pause&powershell -c "type -literalpath '%~f0'|out-string|iex"&pause&exit/b
  2. '';gc -Encoding utf8 'list.txt' |foreach{
  3. "`n开始处理"
  4. $m=[regex]::match($_,'(\+@#@\+)+')
  5. if($m.success){
  6. $fname=$_.substring(0,$m.index)
  7. $fdata=$_.substring($m.index+$m.length)
  8. }else{
  9. $fname=$_
  10. $fdata=""
  11. }
  12. if(($fname -ceq "") -and ($fdata -ceq "")){
  13. echo "这一行是空行"
  14. }else{
  15. if(($fname -ceq '') -and ($m.length -gt 5)){$fname='+@#@+'}
  16. if($fname -ceq ''){
  17. echo '空白的文件名 , 开始添加'
  18. $fname='□'
  19. }
  20. if($fname.length -gt 100){
  21. echo '文件名太长 , 开始截取'
  22. $fname=$fname.substring(0,100)
  23. }
  24. $fname=$fname.split([io.path]::GetInvalidFileNameChars()) -join '□'
  25. $fname='+@#@+'+$fname
  26. if(test-path  -LiteralPath ($pwd.path+"\"+$fname)){
  27. echo '存在同名文件 , 开始调整'
  28. }
  29. $i=$true;$j=1;$k="";while($i){
  30. if(test-path  -LiteralPath ($pwd.path+"\$k"+$fname)){
  31. $j++
  32. $k="[$j]"
  33. }else{$i=$false}
  34. }
  35. if($fdata -ceq ""){
  36. echo ("空的数据流`n将输出到空文件`n"+"$k"+$fname)
  37. [io.file]::WriteAllText($pwd.path+"\$k"+$fname,"")
  38. }else{
  39. echo ("将输出到文件`n"+"$k"+$fname)
  40. [io.file]::WriteAllBytes($pwd.path+"\$k"+$fname,[convert]::FromBase64String($fdata))
  41. }
  42. }
  43. $null
  44. }
复制代码

作者: 304802301    时间: 2024-11-4 14:20

回复 3# Five66


大神!!!可以使用!!
但是现在执行后的文件名是:+@#@+word附件.doc
文件名字前面多了个分隔的这些符号,实际的文件名是word附件.doc,是不是哪一行代码多了什么
作者: czjt1234    时间: 2024-11-4 16:21

回复 4# 304802301


    27行删掉试试
作者: Five66    时间: 2024-11-4 16:24

回复 4# 304802301


   
啊 ,原来不算的么, 可以删掉3楼代码第27行 ,也就是
$fname='+@#@+'+$fname
那一行
作者: aloha20200628    时间: 2024-11-4 19:17

本帖最后由 aloha20200628 于 2024-11-4 19:25 编辑

回复 1# 304802301

win系统内置的 certutil.exe 解码b64效率很高,试试以下这个版本... 存为 test.bat 运行,须与 list.txt 同目录,运行结果会在当前目录下创建一个子目录 ‘解码结果目录’,所需结果文件皆在此目录中... 已用一楼提供的示例样本文件测试通过

  1. @echo off &(md "解码结果目录" &cd "解码结果目录") 2>nul
  2. powershell "foreach($l in [io.file]::ReadLines('..\list.txt')){$n=$l.indexof('+@#@+');if($n -le 0){continue};[io.file]::writeAlltext($l.substring(0,$n)+'.b64',$l.substring($n+5))}"
  3. for /f "delims=" %%F in ('dir /b/a-d *.b64') do certutil -f -decode "%%F" "%%~nF"
  4. del/q *.b64 2>nul
  5. pause&exit/b
复制代码

作者: flashercs    时间: 2024-11-4 22:17

这内存占用太大了.
.NET字符串长度超过2GB,怎么办?certutil 解密base64最大2GB
作者: Five66    时间: 2024-11-5 14:53

回复 8# flashercs


   
额 ,文件数据都用这种形式了 ,应该不至于会弄这么大文件吧
处理超大超长的单行文本只能分块处理了 ,只是 .net 没有字符串(只有char)的分块读取 ,正则也只支持字符串 ,分块处理起来挺麻烦的 ,而且效率也不高
要效率 ,基本上得手动解码




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