Board logo

标题: [文件操作] 批处理怎样提取指定文本? [打印本页]

作者: luonanyun    时间: 2012-6-30 15:59     标题: 批处理怎样提取指定文本?

1.txt内容如下:
  1. 1,D1,40419494.02,2947721.673,596.448
  2. 1,,40419351.35,2947732.962,598.3478
  3. 1,,40419344.61,2947277.154,603.153
  4. 1,,40418602.05,2947109.665,594.418
  5. 1,,40418523.15,2947125.589,594.665
  6. 1,,40418341.76,2946954.128,593.437
  7. 1,D7,40417975.93,2946703.767,588.376
  8. 1,,40417994.06,2946652.564,587.968
  9. 1,,40418082.93,2946562.454,587.923
  10. 1,,40418094.23,2946406.646,584.891
  11. 1,,40418102.05,2946292.159,580.774
复制代码
1.bat内容如下:
  1. @echo off
  2. for /f "delims=, tokens=2,3,4,5" %%a in ('type 1.txt') do (
  3. echo %%a>pul
  4. set sj=%%a
  5. if %sj% neq "" echo %%a%%b%%c%%d>>2.txt
  6. )
  7. pause
复制代码
小弟的意思是以逗号作为分隔符,如果1.txt第二列的哪一行不为空的话就把那一行提取出来,放到2.txt里面,但是我这个批处理双击后本来应该把D1和D7这两行提取出来的,但是一闪而过了,也没生成2.txt,不知道怎么回事,请各位大大给小弟看看,不胜感激!
作者: CrLf    时间: 2012-6-30 16:07

for /f 中,连续的分隔符只起一次分割作用,可以改成:
  1. findstr /vb "[^,]*,," 1.txt >2.txt
复制代码
或这样:
  1. @echo off
  2. (for /f "delims=" %%a in (1.txt) do (
  3.   for /f "delims=0123456789" %%b in ("%%a") do (
  4.     if "%%b"=="," echo %%a
  5.   )
  6. ))>2.txt
  7. pause
复制代码

作者: luonanyun    时间: 2012-6-30 16:53

回复 2# CrLf
  1. @echo off
  2. (for /f "delims=" %%a in (1.txt) do (
  3.   for /f "delims=0123456789" %%b in ("%%a") do (
  4.     if "%%b"=="," echo %%a
  5.   )
  6. ))>2.txt
  7. pause
复制代码
版主大大,这段代码我刚才试了一下什么也没提取出来,就新建了一个空的2.txt.......
  1. for /f "delims=0123456789" %%b in ("%%a") do (
  2.     if "%%b"=="," echo %%a
  3.   )
复制代码
这段没看懂,delim=0123456789是什么意思啊,还有就是怎么什么也没处理就直接判断了啊?请版主大大不吝赐教!
作者: weichenxiehou    时间: 2012-6-30 17:12

  1. @echo off
  2. (for /f "delims=" %%a in (1.txt) do (
  3.   for /f "tokens=2 delims=0123456789" %%b in ("%%a") do (
  4.     if "%%b"=="," echo %%a
  5.   )
  6. ))>2.txt
  7. pause
复制代码
版主事务太多,看来也少了亲测。。
作者: luonanyun    时间: 2012-6-30 17:48

本帖最后由 luonanyun 于 2012-6-30 17:49 编辑

回复 4# weichenxiehou


   呵呵 非常感谢,我后来也想了个方法提取,但是没大大的好用!
  1. @echo off
  2. echo 正在提取。。。。。。
  3. for /f "tokens=*" %%a in ('type 1.txt') do (
  4. echo "%%a" | find /i "D">nul && for /f "tokens=* delims=," %%b in ("%%a") do (
  5. echo %%b>>2.txt
  6. )
  7. )
  8. pause
复制代码
我这个只能提取包含指定字符的那一行,没大大那个好用,呵呵!能解释下delims=0123456789是什么意思么,谢谢!还有就是%%b=,也没懂
作者: forfiles    时间: 2012-6-30 18:09

回复 5# luonanyun


    用数字作为列分隔符
作者: luonanyun    时间: 2012-6-30 19:57

回复 4# weichenxiehou


    大大,您这代码如果中间只有一个字母的话那就提取不出来了!.....
作者: CrLf    时间: 2012-6-30 21:25

回复 3# luonanyun


    没注意你的样本里还有字母,修改下:
  1. @echo off
  2. (for /f "delims=" %%a in (1.txt) do (
  3.   for /f "delims=0123456789" %%b in ("%%a") do (
  4.     if "%%b" neq ",," echo %%a
  5.   )
  6. ))>2.txt
  7. pause
复制代码

作者: poter    时间: 2012-6-30 21:35

我的方法笨了一点
@echo off
setlocal enableDelayedExpansion
for /f "tokens=*" %%i in (1.txt) do (
        set str=%%i&set "str=!str:,,=,nothing,!"
        for /f "tokens=2 delims=," %%j in ("!str!") do (
                if not "%%j"=="nothing" echo %%i>>2.txt
        )
)
作者: weichenxiehou    时间: 2012-6-30 22:31

回复 7# luonanyun
代码是版主写的,叫我来解释,我怕卷进版权风波啊~~
delims=0123456789表示把所有的数字视为分隔符,那么想象一下,将所有的数字作为分隔符后,文本成什么样?
  1. [分隔],D[分隔],[分隔].[分隔],[分隔].[分隔],[分隔].//要提取的行
  2. [分隔],,[分隔].[分隔],[分隔].[分隔],[分隔].       //不要的行
  3. ...
复制代码
明显区别是,要提取的行的第二列为“,”,而不要的行第二列不是,这只是版主根据顶楼的数据总结的规律,然后写的代码;如果第二列只有字母(假设为一个D),那么切割的结果为:
  1. [分隔],D,[分隔].[分隔],[分隔].[分隔],[分隔].
复制代码
那么用第二列是否为“,”来判断显然不行了,因为这种行第二列切割后并不是",“。
所以你可以用版主修改的8楼的代码或2楼的findstr方法,或者9楼的先替换再判断,当然也可以用sed:
  1. sed -nr "/^([a-zA-Z0-9]+,){2}/p" 1.txt>2.txt
复制代码
当然,用gawk也挺方便:
  1. gawk -F, "$2!=\"\"" 1.txt>2.txt
复制代码

作者: FOR    时间: 2012-6-30 22:39

  1. @echo off
  2. for /f "delims=" %%I in (b.txt) do (
  3. set "var=%%I"
  4. setlocal enabledelayedexpansion
  5. set "str=!var:,,=, ,!"
  6. for /f "tokens=2 delims=," %%a in ("!str!") do (
  7. if not "%%a"==" " echo;!var!
  8. )
  9. endlocal
  10. )
  11. pause
复制代码

作者: CrLf    时间: 2012-6-30 22:59

本帖最后由 CrLf 于 2012-6-30 23:13 编辑

练一下 vbs...
split 方案:
  1. Option Explicit
  2. Dim FSO,File,f,str,ar
  3. Const ForRead = 1
  4. Const ForWrite = 2
  5. Set FSO = CreateObject("Scripting.FileSystemObject")
  6. Set File = FSO.OpenTextFile("1.txt",ForRead)
  7. Do While Not File.AtEndOfStream
  8. f = File.ReadLine
  9. ar = Split(f,",")
  10. If UBound(ar)>2 Then
  11. If ar(1)<>"" Then
  12. str = str & f & vbCrLf
  13. End If
  14. End If
  15. Loop
  16. File.Close
  17. Set File = FSO.CreateTextFile("2.txt",ForWrite,True)
  18. File.Write str
  19. File.Close
复制代码
写得很丑陋的正则方案:
  1. Option Explicit
  2. Dim re,FSO,File,f,str,a,ar
  3. Const ForRead = 1
  4. Const ForWrite = 2
  5. Set re = New RegExp
  6. re.Pattern = "^[^,]*,[^,]+.*"
  7. re.Global = True
  8. re. Multiline = True
  9. Set FSO = CreateObject("Scripting.FileSystemObject")
  10. Set File = FSO.OpenTextFile("1.txt",ForRead)
  11. f = File.ReadAll
  12. File.Close
  13. Set ar = re.Execute(f)
  14. For Each a In ar
  15. str = str & a.value
  16. Next
  17. Set File = FSO.CreateTextFile("2.txt",ForWrite,True)
  18. File.Write str
  19. File.Close
复制代码
结论:还是 findstr 方便
作者: luonanyun    时间: 2012-6-30 23:28

本帖最后由 luonanyun 于 2012-7-1 09:28 编辑

回复 8# CrLf


    呵呵 成功了!
排名不分先后:感谢版主“CrLf ”大大、“weichenxiehou”大大、“forfiles ”大大、“poter ”大大 “FOR”大大
小弟在这里祝各位大大:长命百岁、寿比南山,出门挣大钱!
作者: FOR    时间: 2012-7-1 01:50

findstr /bv "[0-9],," b.txt




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