Board logo

标题: [文本处理] 批处理命令findstr判断是否存在指定字符并替换,输出结果中有原始行内容是什么原因? [打印本页]

作者: huamz    时间: 2017-3-28 10:20     标题: 批处理命令findstr判断是否存在指定字符并替换,输出结果中有原始行内容是什么原因?

txt转csv时遇到的问题,请高人指点
想把一个txt文件换转为csv,转换后的csv文件要满足:第二列后插入一列(即在每行的第20个字符前插入一列),值为最后一列的正负标识(正为B,负为S)
注:txt 文件中各项间有空格和tab(见图),数据很多,需要高效代码。
首先是用for读文件,然后判断是否有字符"-"(即负号),如有则将"-"替换为"S " (S后有tab),如没有则在第20个字符前插入"B "(B后也有tab)
最后,将str中tab替换为,后写入csv.
上网参考了很多代码,都不行,请高人指点。

我的代码如下。
  1. @echo off
  2. @echo off&setlocal enabledelayedexpansion
  3. echo     92502      608     -300>a.txt
  4. echo     92502      608    -1000>>a.txt
  5. echo     92502      608     2500>>a.txt
  6. echo     92502      608     6955>>a.txt
  7. echo     92502      608     1800>>a.txt
  8. echo     92502      608     4800>>a.txt
  9. for %%a in (a.txt) do (
  10. (for /f "usebackq delims=" %%b in ("%%a") do (
  11. set "str=%%b"
  12. echo %%b | findstr /c:"-" && (set "str=!str:-=S !"
  13. ) || (set "str=!str:~0,20!B !str:~20,8!
  14. )
  15.     echo !str: =,!
  16.   ))>"%%~na.csv"
  17. )
复制代码
主要问题是:负数行会生成两行!!!!
请高人看看问题在哪?
作者: pcl_test    时间: 2017-3-28 10:37

还用findstr匹配的结果,屏蔽掉即可
作者: ShowCode    时间: 2017-3-28 10:48

findstr /c:"-" > nul
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. echo     92502      608     -300>a.txt
  4. echo     92502      608    -1000>>a.txt
  5. echo     92502      608     2500>>a.txt
  6. echo     92502      608     6955>>a.txt
  7. echo     92502      608     1800>>a.txt
  8. echo     92502      608     4800>>a.txt
  9. for %%a in (a.txt) do (
  10.     (for /f "usebackq delims=" %%b in ("%%a") do (
  11.         set "str=%%b"
  12.         echo %%b | findstr /c:"-" > nul && set "str=!str:-=S !" || set "str=!str:~0,20!B !str:~20,8!"
  13.         echo !str: =,!
  14.     ))>"%%~na.csv"
  15. )
复制代码

作者: huamz    时间: 2017-3-28 10:57

谢谢2楼,解决了。
作者: ShowCode    时间: 2017-3-28 11:22

提醒一下,顶楼代码13行结尾少了个双引号。
作者: Nsqs    时间: 2017-3-28 13:30

本帖最后由 Nsqs 于 2017-3-28 15:14 编辑

问题
1.没有delims
2.-替换为S,那么最后一列的-号不就没了
  1. @powershell -c $f='a.txt';$r=(Get-Content -raw $f) -replace '[ \t]+(\d+)[ \t]+(\d+)[ \t]+([^-]\d+)',' $1, $2,B, $3';Set-Content ($f -replace '(.+)\..+','$1.csv') -Value ($r -replace  '[ \t]+(\d+)[ \t]+(\d+)[ \t]+(-\d+)',' $1, $2,S, $3')
复制代码

作者: huamz    时间: 2017-3-31 10:48

谢谢Nsqs,ShowCode两位指点。
现在试了一下,感觉用批处理太慢了,这个txt有上万条记录。
我准备用sql里面的bcp再试试了
作者: pcl_test    时间: 2017-3-31 12:18

  1. @echo off&setlocal enabledelayedexpansion
  2. set "file=a.txt"
  3. (for /f "delims=" %%a in ('type "%file%"') do (
  4.     for %%b in (%%a) do (
  5.         if defined str set /p=!str!,
  6.         set "str=%%b"
  7.     )
  8.     if "!str:~,1!" equ "-" (echo;S,!str!) else echo;B,!str!
  9.     set "str="
  10. ))<nul>"%file:~,-4%.csv"
  11. pause
复制代码

作者: ShowCode    时间: 2017-3-31 13:12

回复 7# huamz


    如果你的原始数据都是放在数据库里面的,那当然是SQL更快啦




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