Board logo

标题: [文本处理] BAT批量分析并整理CAD图纸内包含的工程项目【用PowerShell已完美解决】 [打印本页]

作者: xy506    时间: 2018-8-28 14:52     标题: BAT批量分析并整理CAD图纸内包含的工程项目【用PowerShell已完美解决】

本帖最后由 xy506 于 2018-8-29 19:25 编辑

一、需求起因:手上有大量CAD图纸、图纸文件内包含不定量工程项目的图纸。现需要整理出每个图纸文件中包含有哪些工程项目。
示例图纸包:链接: https://pan.baidu.com/s/1mIsue6Ek-GhwaKhNVMVpAg 密码: cri3
二、解决思路:
1、先通过AcmeCADConverter_Por软件将DWG格式的图纸转换为DXF文件,并将DXF文件绝对路径导出至:文件列表.txt
AcmeCADConverter_Por下载地址:
链接: https://pan.baidu.com/s/1P9WMulPuK0c3EqeaGdd0eQ 密码: qi24
2、然后通过批处理将DXF文件作为文本文档处理,提取出包含“工程”、“图”的文本行并另存为以DXF图纸文件名命名的TXT文档内。批处理代码如下:
  1. @echo off & setlocal EnableDelayedExpansion
  2. set j=0
  3. for /f "delims=" %%i in (文件列表.txt) do (
  4. set /a j+=1
  5. set con!j!=%%i
  6. call set a=%%con!j!%%
  7. type !a! | find "工程" >> "!a!.txt"
  8. type !a! | find "图" >> "!a!.txt"
  9. @echo off
  10. )
复制代码
3、通过批处理将以DXF图纸文件名命名的TXT文档内重复的行、不符合要求的行删除并不保留空行。
去除重复行功能谢谢管理员在三楼给出的代码试用后成功处理了重复行代码:
  1. @echo off
  2. md "去重之后的文件"
  3. for /f "delims=" %%i in ('dir /b /s *.txt') do (
  4.     echo 正在处理文件 %%i
  5.     setlocal
  6.     (for /f "delims=" %%a in ('type "%%i"') do (
  7.         if not defined _%%a (
  8.             echo,%%a
  9.             set "_%%a=1"
  10.         )
  11.     ))>"去重之后的文件\%%~ni.log"
  12.     endlocal
  13. )
复制代码
现在还差去除不需要的数据了。
去除不需要的数据,个人想法:
3.1、删除每一行内多余的空格,
3.2、删除少于6个汉子内容的行,
3.3、删除"数据链接^"、"C:\或者D:\等盘符地址"开头的行
3.4、提取:“((FRAME .”开头的行中(PLOTFILEPREFIX . "******(工程名称)******_")这一段""双引号内的内容其余部分删除
4、将整理好的文本文档处理为电子表格,第一列为文件名,后面依次填写文件内包含的工程名称。
三、遇到的问题:1、在处理TXT文档内重复的行、不符合要求的行删除并不保留空行时,单个文档可以处理,但是用变量批处理就不行了。
单个处理代码如下
  1. @echo off
  2. (for /f "delims=" %%i in (XXX.txt) do findstr "%%i" "XXX2.txt">nul||echo %%i)>XXX2.txt
  3. )
  4. pause
复制代码
2、如何按条件删除不符合条件的行的代码也不会写。
3、如何将大量TXT文档处理成电子表格也暂时没想到解决办法。


谢谢论坛里的大神~~问题解决了~附上最终代码:
  1. $start = Get-Date #记录脚本开始执行时间
  2. ForEach( $file In (dir "*.dxf") ) {  #这里加了双引号,不加双引号的时候会出现找不到路径报错
  3.     $arr = [IO.File]::ReadAllLines($file, [Text.Encoding]::Default);
  4.     $arr = $arr -match '工程|图' -replace '\s+';                          #匹配包含"工程" 或 "图"的行、删除空格
  5.     $arr = $arr -replace '^\(\(FRAME.*PLOTFILEPREFIX."([^"]+)".*$', '$1';
  6.     $arr = $arr -NotMatch '^.{1,5}$|数据链接\^|[c-zC-Z]:\\|"TCH_KERNAL|接图|图例|在选择|说明|关闭|宋体'               #删除不符合要求的行
  7.     $arr = $arr | sort -Unique;                                           #删除重复行
  8.     $str += '"' + $file.Name + '","' + ($arr -join '","') + '"' + "`r`n";
  9. }
  10. #Get-ChildItem variable:  #显示出变量的值以便查看问题出现在哪里
  11. sc a.CSV -Value $str;
  12. $end = Get-Date #记录脚本结束执行时间
  13. Write-Host -ForegroundColor Red ('Total Runtime: ' + ($end - $start).TotalSeconds) #显示脚本执行时间
复制代码

作者: Batcher    时间: 2018-8-28 15:30

1.bat
  1. @echo off
  2. md "去重之后的文件"
  3. for /f "delims=" %%i in ('dir /b /s *.txt') do (
  4.     (for /f "delims=" %%a in ('type "%%i"') do (
  5.         findstr /x /c:"%%a" "去重之后的文件\%%~ni.log" 1>nul 2>&1 || echo,%%a
  6.     ))>"去重之后的文件\%%~ni.log"
  7. )
复制代码

作者: xy506    时间: 2018-8-28 18:12

回复 2# Batcher


试了下 不行 点一次只处理一个文件就会卡死,再点的时候就提示:另一个程序正在使用此文件,进程无法访问。
作者: Batcher    时间: 2018-8-28 21:55

回复 3# xy506


没有卡死,只是处理的比较慢而已。因为文件比较大,那个去重的方法需要不停的调用findstr命令,所以效率不高。
可以用另外一种去重的方法试试:
  1. @echo off
  2. md "去重之后的文件"
  3. for /f "delims=" %%i in ('dir /b /s *.txt') do (
  4.     echo 正在处理文件 %%i
  5.     setlocal
  6.     (for /f "delims=" %%a in ('type "%%i"') do (
  7.         if not defined _%%a (
  8.             echo,%%a
  9.             set "_%%a=1"
  10.         )
  11.     ))>"去重之后的文件\%%~ni.log"
  12.     endlocal
  13. )
复制代码

作者: WHY    时间: 2018-8-29 01:07

我试了下,AcmeCADConverter_Por 转换成的 dxf 文件,编码格式为 UTF8 without BOM
这样的话,find 或 findstr 应该不可以,楼主是怎么做到的?
作者: WHY    时间: 2018-8-29 01:11

PowerShell 脚本,使用方法请咨询搜索引擎
  1. ForEach( $file In (dir *.dxf) ) {
  2.     $arr  = [IO.File]::ReadAllLines($file, [Text.Encoding]::UTF8);
  3.     $arr = $arr -match '工程|图' -NotMatch '"' | sort -Unique; #找到 工程 或 图 的行,去掉 引号 的行,再去重。
  4.     $str += '"' + $file.Name + '","' + ($arr -join '","') + '"' + "`r`n";
  5. }
  6. sc a.CSV -Value $str;
复制代码

作者: xy506    时间: 2018-8-29 11:05

回复 5# WHY


    额,我的导出来以后直接就是GB2312的编码啊
作者: xy506    时间: 2018-8-29 12:18

回复 6# WHY


   执行了,但是反馈的CSV文档只有DXF文件的文件名
作者: xy506    时间: 2018-8-29 12:26

回复 4# Batcher


   这个可以运行,谢谢啦。
作者: xy506    时间: 2018-8-29 15:51

回复 6# WHY


   因我导出的DXF文件都是GB2312格式的编码,所以我把你的代码中UTF8改成GB2312了 执行时提示:
  1. 使用“2”个参数调用“ReadAllLines”时发生异常:“值不能为 null。
  2. 参数名: encoding”
  3. 所在位置 H:\历年验收图纸\2011年验收\筛选导出CSV.PS1:2 字符: 5
  4. +     $arr  = [IO.File]::ReadAllLines($file, [Text.Encoding]::GB2312);
  5. +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  6.     + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
  7.     + FullyQualifiedErrorId : ArgumentNullException
复制代码

作者: WHY    时间: 2018-8-29 16:01

本帖最后由 WHY 于 2018-8-29 16:53 编辑
  1. ForEach( $file In (dir *.dxf) ) {
  2.     $arr = [IO.File]::ReadAllLines($file, [Text.Encoding]::UTF8);
  3.     $arr = $arr -match '工程|图' -replace '\s+';                          #匹配包含"工程" 或 "图"的行、删除空格
  4.     $arr = $arr -replace '^\(\(FRAME.*PLOTFILEPREFIX."([^"]+)".*$', '$1';
  5.     $arr = $arr -NotMatch '^.{1,5}$|数据链接\^|[c-zC-Z]:\\'               #删除不符合要求的行
  6.     $arr = $arr | sort -Unique;                                           #删除重复行
  7.     $str += '"' + $file.Name + '","' + ($arr -join '","') + '"' + "`r`n";
  8. }
  9. sc a.CSV -Value $str;
复制代码
Win10 v1803 测试没有问题
作者: WHY    时间: 2018-8-29 16:03

回复 10# xy506


PS C:\Users\WHY> [text.Encoding]:efault


BodyName          : gb2312
EncodingName      : 简体中文(GB2312)
HeaderName        : gb2312
WebName           : gb2312
WindowsCodePage   : 936
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
IsSingleByte      : False
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : True
CodePage          : 936

作者: xy506    时间: 2018-8-29 19:05

本帖最后由 xy506 于 2018-8-29 19:06 编辑

回复 11# WHY


   谢谢你的建议,你这个代码执行还是有问题,我简单修改了一下已经可以了,修改后的内容如下:
  1. ForEach( $file In (dir "*.dxf") ) {  #这里加了双引号,不加双引号的时候会出现找不到路径报错
  2.     $arr = [IO.File]::ReadAllLines($file, [Text.Encoding]::Default);
  3.     $arr = $arr -match '工程|图' -replace '\s+';                          #匹配包含"工程" 或 "图"的行、删除空格
  4.     $arr = $arr -replace '^\(\(FRAME.*PLOTFILEPREFIX."([^"]+)".*$', '$1';
  5.     $arr = $arr -NotMatch '^.{1,5}$|数据链接\^|[c-zC-Z]:\\|"TCH_KERNAL|接图|图例|在选择'               #删除不符合要求的行
  6.     $arr = $arr | sort -Unique;                                           #删除重复行
  7.     $str += '"' + $file.Name + '","' + ($arr -join '","') + '"' + "`r`n";
  8. }
  9. #Get-ChildItem variable:  #显示出变量的值以便查看问题出现在哪里
  10. sc a.CSV -Value $str;
复制代码





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