标题: [文本处理] [已解决]批处理把以双竖线为分隔符,把指定列替换成问号 [打印本页]
作者: leo1984 时间: 2009-1-25 18:18 标题: [已解决]批处理把以双竖线为分隔符,把指定列替换成问号
請教各位好心的前輩幫忙
我有一個文件夾,裡頭有許多txt文本,全部都要處理
以∥作為分隔符
我想要在文本第一行后面的每一行作處理
a∥b∥c∥d∥e∥f∥g∥h∥i∥j∥k∥l∥
我想要將c的部份用 "?" 符號取代
請問該如何作呢?謝謝
作者: wxcute 时间: 2009-1-25 19:52
放在文本文件同目录下执行,生成新文件 new_原文件名.txt- @echo off
- setlocal enabledelayedexpansion
- for /f "delims=" %%i in ('dir/b *.txt') do (
- for /f "usebackq skip=1 tokens=1-3* delims=/" %%j in ("%%i") do (
- if not exist "new_%%i" (
- set/p first=<"%%i"
- echo !first!>"new_%%i"
- )
- echo %%j//%%k//?//%%m>>"new_%%i"
- )
- )
- pause
复制代码
作者: leo1984 时间: 2009-1-25 20:26
給樓上的前輩
我使用您的代碼後
替換的是F的內容
但是我要替換的是C的內容
請問該怎麼作呢?
感謝您!
作者: leo1984 时间: 2009-1-25 20:30
- @echo off
- setlocal enabledelayedexpansion
- for /f "delims=" %%i in ('dir/b *.txt') do (
- for /f "usebackq skip=1 tokens=1-3* delims=∥" %%j in ("%%i") do (
- if not exist "new_%%i" (
- set/p first=<"%%i"
- echo !first!>"new_%%i"
- )
- echo %%j∥%%k∥?∥%%m>>"new_%%i"
- )
- )
- pause
复制代码
啊是我搞錯了
前輩您沒寫錯
我修改正確的分隔符就可以了
感謝
作者: leo1984 时间: 2009-1-25 22:00
不好意思前輩,再麻煩您
問題一:
請問我要在這些文本中,只要每行有出現<<錯誤>>這個字符,就直接將該行刪除
問題二:
只要文本內其中有一行,不符合十二個∥分隔符,就將該文本移動到別的文件夾
請問該如何寫呢?
感謝!
作者: defanive 时间: 2009-1-25 23:26
用findstr配合。。。
用sed等第三方工具方便吧,用for做太麻烦了。。。
作者: leo1984 时间: 2009-1-25 23:37
原帖由 defanive 于 2009-1-25 23:26 发表
用findstr配合。。。
用sed等第三方工具方便吧,用for做太麻烦了。。。
不太瞭解您所講的
請問該怎麼使用呢?
小弟這方面還沒學習過
因為網站的資料要處理,經過友人推薦來此討教
希望給新手多包含指點
作者: leo1984 时间: 2009-1-26 03:30
另外請教wxcute版主
您給我的代碼,只要處理文本內含有 "!" "?" ":" "<" 字符,就會跳過不處理
請問要如何忽略過這些字符正常處理呢?
謝謝
作者: wxcute 时间: 2009-1-27 11:32
使用前请备份,以免数据丢失。还有可以先用部分数据测试。
其中 “Tmp_原名” 为中间文件,即去掉含 “错误” 字符串的行,因为无法整合处理,所以改用临时文件。
“new_原名” 为最终生成文件。- @echo off
- echo 使用前请先备份好数据……
- echo 备份好后按任意键开始。
- pause>nul
- if not exist Not12\ md Not12
- for /f "delims=" %%X in ('dir/b *.txt') do (
- set flag=
- call :wordErr "%%X"
- call :judge12 "Tmp_%%X"
- if not defined flag for /f "usebackq skip=1 tokens=1-12* delims=∥" %%a in ("Tmp_%%X") do (
- if not exist "new_%%X" call :firstL "%%X"
- echo %%a∥%%b∥?∥%%d∥%%e∥%%f∥%%g∥%%h∥%%i∥%%j∥%%k∥%%l>>"new_%%X"
- )
- )
- pause
-
- :firstL
- set/p first=<%1
- echo %first%>"new_%~1"
- goto :eof
- :judge12
- for /f "usebackq skip=1 tokens=1-12* delims=∥" %%a in (%1) do (
- if "%%l"=="" set flag=1
- if not "%%m"=="" set flag=1
- )
- if defined flag move "%~1" Not12
- goto :eof
- :wordErr
- cd.>"Tmp_%~1"
- for /f "delims= eol=" %%i in ('findstr /v "<<錯誤>>" %1') do (
- echo+%%i>>"Tmp_%~1"
- )
复制代码
作者: leo1984 时间: 2009-1-28 22:53
原帖由 wxcute 于 2009-1-27 11:32 发表
使用前请备份,以免数据丢失。还有可以先用部分数据测试。
其中 “Tmp_原名” 为中间文件,即去掉含 “错误” 字符串的行,因为无法整合处理,所以改用临时文件。
“new_原名” 为最终生成文件。@echo off
echo 使 ...
抱歉
過年期間回老家一直沒能上來答覆
我試用了您的代碼後
發現沒有生成new文件
也就是?字符沒有進行替換
請問是為什麼呢?
感謝!
作者: 随风 时间: 2009-1-29 01:30
未测试。。
建议给出样本文件
仍有几个疑问
如你5楼所说。
只要文本內其中有一行,不符合十二個∥分隔符,就將該文本移動到別的文件夾
对于此句中的 “不符合十二個∥分隔符” 我有多个理解。
1、∥∥∥∥∥∥∥∥∥∥∥∥abcd∥ 这算有12个吗?
2、∥1∥2∥3∥4∥5∥∥∥∥6∥7∥8∥9∥10∥11∥ 这算有12个吗?
以下代码对 “符合十二個∥分隔符” 的定义是:
1、连续的∥算作一个
2、每行首尾的∥被忽略。
3、不足12个∥的就將該文本移動到別的文件夾,但多于12个的则不会。
代码未测试,并会改写源文件,测试前勿必作备份。。。切记!!!
:- @echo off
- md sss
- for /f "delims=" %%A in ('dir/b *.txt') do (
- cd.>xx.txt
- set var=&set flag=a
- for /f "tokens=1-3* delims=∥" %%a in ('findstr /iv "錯誤" "%%A"') do (
- >>xx.txt echo %%a∥%%b∥?∥%%d
- for /f "tokens=13 delims=∥" %%B in ("%%a∥%%b∥?∥%%d") do set "flag="
- if defined flag set var=a
- )
- if defined var move "%%A" "sss"&del/q xx.txt
- if exist xx.txt move "xx.txt" "%%A"
- )
- pause
复制代码
作者: terse 时间: 2009-1-29 01:47
- @echo off
- if not exist Not12\ md Not12
- for /f "delims=" %%i in ('dir/b /a-d *.txt') do call :lp "%%i"
- exit
- :lp
- for /f "tokens=1-12* delims=∥" %%a in ('findstr /iv "<<錯誤>>" %1') do (
- if "%%l"=="" (move %1 "Not12\%~1"& del "Not12\new_Tmp_%~1" 2>nul&exit/b)else (
- >>"new_Tmp_%~1" echo %%a∥%%b∥?∥%%d∥%%e∥%%f∥%%g∥%%h∥%%i∥%%j∥%%k∥%%l∥
- ))
复制代码
作者: leo1984 时间: 2009-1-29 03:44
原帖由 随风 于 2009-1-29 01:30 发表
未测试。。
建议给出样本文件
仍有几个疑问
如你5楼所说。
只要文本內其中有一行,不符合十二個∥分隔符,就將該文本移動到別的文件夾
对于此句中的 “不符合十二個∥分隔符” 我有多个理解。
1、∥∥∥∥∥∥ ...
我測試過您的代碼
不太合理@@
我需求的是:
1:先進行?字符先取代
2:接著要完全符合12個∥分隔符,多或少都不能
謝謝你的答覆^^
以下幾個範本供您測試
[ 本帖最后由 leo1984 于 2009-1-29 03:52 编辑 ]
作者: leo1984 时间: 2009-1-29 03:49
原帖由 terse 于 2009-1-29 01:47 发表
@echo off
if not exist Not12\ md Not12
for /f "delims=" %%i in ('dir/b /a-d *.txt') do call :lp "%%i"
exit
:lp
for /f "tokens=1-12* delims=∥" %%a in ('findstr /iv "" %1') do (
if "%%l"=="" (mov ...
前輩
沒想到在這裡也看到您
真是熱心的人
在這跟你拜個年~~祝 健康順心
我測試您的代碼後
not12文件夾內的都是符合12個∥分隔符的文本
並且沒有進行?字符的取代
是不是處理方式搞反了呢?
謝謝
[ 本帖最后由 leo1984 于 2009-1-29 03:57 编辑 ]
作者: wxcute 时间: 2009-1-29 14:26
问题一、样本没有含 “错误” 字样的行
二、样本中没有非 12 个分隔符的行
三、样本首行与其他行没什么区别
以下代码不能处理一行中引号数为单数的情况。- @echo off
- if not exist Not12\ md Not12
- for /f "delims=" %%X in ('dir/b *.txt') do (
- set flag=
- call :wordErr "%%X"
- for /f "usebackq skip=1 delims=" %%i in ("Tmp_%%X") do (
- call :judge12 "%%i"
- )
- if defined flag move "Tmp_%%X" Not12
- if not defined flag for /f "usebackq tokens=1-3* delims=‖" %%a in ("Tmp_%%X") do (
- if exist "new_%%X" (
- echo %%a‖%%b‖?‖%%d>>"new_%%X"
- ) else echo %%a‖%%b‖%%c‖%%d>"new_%%X"
- )
- )
- pause
-
- :judge12
- set n=
- set contain=%1
- :lp
- set contain=%contain:*‖="%
- set/a n+=1
- if %n% lss 12 (
- if %contain%=="" set flag=1
- goto :lp
- )
- if not %contain%=="" set flag=1
- goto :eof
- :wordErr
- cd.>"Tmp_%~1"
- for /f "delims= eol=" %%i in ('findstr /v "\<\<錯誤>>" %1') do (
- echo+%%i>>"Tmp_%~1"
- )
复制代码
作者: terse 时间: 2009-1-29 16:29
这样可以不- @echo off
- if not exist Not12\ md Not12
- for /f "delims=" %%i in ('dir /b /a-d "*.txt"') do call:lp "%%i"
- pause&exit
- :lp
- for /f "tokens=1-3* delims=‖" %%a in ('findstr /iv "<<錯誤>>" %1') do (
- set "str=%%d"
- setlocal enabledelayedexpansion
- for /l %%i in (1 1 9) do (
- set "str=!str:*‖=!"
- )
- if "!str!"=="" (
- endlocal
- >>"new_Tmp_%~1" echo %%a‖%%b‖?‖%%d
- ) else (
- move %1 "Not12\%~1"& del "new_Tmp_%~1" 2>nul&exit/b
- ))
复制代码
作者: leo1984 时间: 2009-1-31 02:52
原帖由 wxcute 于 2009-1-29 14:26 发表
问题一、样本没有含 “错误” 字样的行
二、样本中没有非 12 个分隔符的行
三、样本首行与其他行没什么区别
以下代码不能处理一行中引号数为单数的情况。@echo off
if not exist Not12\ md Not12
f ...
抱歉,过完年回来电脑被孩子玩坏,慢点回覆请多包含
前辈我使用您的代码后如下图,不能运行
另外我上传了两个错误的文本给您测试
第一个是含有错误的文本
第二个是含有少于十二个‖的文本
而因为这是网站的资料文本,第一行保留下来,是因为那是文章的标题,第二行以后就不需要文章标题,所以改用?字符禁止读取
麻烦您再帮忙
再次感谢您辛劳
作者: leo1984 时间: 2009-1-31 02:58
原帖由 terse 于 2009-1-29 16:29 发表
这样可以不@echo off
if not exist Not12\ md Not12
for /f "delims=" %%i in ('dir /b /a-d "*.txt"') do call:lp "%%i"
pause&exit
:lp
for /f "tokens=1-3* delims=‖" %%a in ('findstr /iv "" %1') do (
...
您的代碼是可以運行的
但是我需要忽略第一行,對其他行進行處理
我加入skip=1 好像也不行,會直接刪除第一行
可以麻煩您再修改嗎?
還有您上次在"非常批處理"網站給我的代碼
非常好用
再次感謝您!
作者: terse 时间: 2009-1-31 13:23
这样呢?- @echo off
- if not exist Not12\ md Not12
- for /f "delims=" %%i in ('dir /b /a-d "*.txt"') do set "str="&call:lp "%%i"
- pause&exit
- :lp
- for /f "tokens=1-3* delims=‖" %%a in ('findstr /iv "<<錯誤>>" %1') do (
- if not defined str (set str=%%i&>>"new_Tmp_%~1" echo %%a‖%%b‖%%c‖%%d)else (
- set "str=%%d"
- setlocal enabledelayedexpansion
- for /l %%i in (1 1 9) do (
- set "str=!str:*‖=!"
- )
- if "!str!"=="" (
- endlocal
- >>"new_Tmp_%~1" echo %%a‖%%b‖?‖%%d
- ) else (
- move %1 "Not12\%~1"& del "new_Tmp_%~1" 2>nul&exit/b
- )))
复制代码
作者: leo1984 时间: 2009-1-31 16:00
原帖由 terse 于 2009-1-31 13:23 发表
这样呢?@echo off
if not exist Not12\ md Not12
for /f "delims=" %%i in ('dir /b /a-d "*.txt"') do set "str="&call:lp "%%i"
pause&exit
:lp
for /f "tokens=1-3* delims=‖" %%a in ('findstr /iv "" %1 ...
我剛才用您代碼測試
發現符合十二個‖分隔符的文本,也會被分類在Not12文件夾裡
我上傳一個文本供您測試
麻煩您
作者: terse 时间: 2009-2-1 13:52
发现前面有空的值就会错误 先用下面试看了 不过那也不是办法 特征太少
%%a %%b为空有错出现 因为没有特征 所以只要前面有一个空 就判断不了是哪个- @echo off
- if not exist Not12\ md Not12
- for /f "delims=" %%i in ('dir /b /a-d "*.txt"') do set str=&call:lp "%%i"
- pause&exit
- :lp
- for /f "delims=" %%a in ('findstr /iv "<<錯誤>>" %1') do (
- if not defined str (set str=a&>"new_Tmp_%~1" echo %%a)else (
- set "str=%%a"&set "str1=%%a"
- setlocal enabledelayedexpansion
- for /l %%i in (1 1 12) do (
- set "str=!str:*‖=!"
- if %%i equ 3 set var=!str!
- )
- if "!str!"=="" (
- for /f "tokens=1-3* delims=‖" %%a in ("!str1!") do >>"new_Tmp_%~1" echo %%a‖%%b‖?‖!var!
- endlocal
- ) else (
- endlocal
- move %1 "Not12\%~1"& del "new_Tmp_%~1" 2>nul&exit/b
- )))
复制代码
[ 本帖最后由 terse 于 2009-2-2 15:05 编辑 ]
作者: leo1984 时间: 2009-2-1 16:00
原帖由 terse 于 2009-2-1 13:52 发表
发现前面有空的值就会错误 先用下面试看了 不过那也不是办法 特征太少
%%a %%b为空有错出现 因为没有特征 所以只要前面有一个空 就判断不了是哪个@echo off
if not exist Not12\ md Not12
for /f "delims=" % ...
謝謝您的幫忙
不過我剛測試,每個文本的第一行後頭都會多加上∥%b∥%c∥%d這樣一段多餘的字符
請問可以再修正嗎?
作者: namejm 时间: 2009-2-1 19:15
你的文字描述和你提供的文本有一些出入,所谓差之毫厘谬以千里,所以,有几个问题需要确认一下:
1、分隔符号究竟是//还是‖?
2、究竟是要删除含有 <<删除>> 字符串的行还是含有 <<错误>> 的行?
3、多个‖连在一起算一个还是算多个?
作者: namejm 时间: 2009-2-1 19:20
要消除每个文本第一行之后多出来的字符串,应该这样修改代码:在:lp的下一行添加一条语句 set "str="
作者: wxcute 时间: 2009-2-1 20:15
条件总结如下:
一、先删除文本中包含 <<删除>> 字串的行;
二、处理一行为 12 个 ‖ 作为分隔符的文本,只要有一行不是 12 个分隔符,就放到一个单独的目录中;
其中不考虑第一行,而且分隔符连续出现时分开算个数
三、将第三列替换为问号。
其中头两列不为空
一行中的感叹号不能太多,多了就要将 set txtL=%%i%%j%%k%%l%%m 加长。- @echo off
- if not exist Not12\ md Not12
- for /f "delims=" %%X in ('dir/b *.txt') do (
- set flag=
- call :wordErr "%%X"
- for /f "usebackq skip=1 tokens=1-4* delims=!" %%i in ("Tmp_%%X") do (
- set txtL=%%i%%j%%k%%l%%m
- setlocal enableDelayedExpansion
- set txtL=!txtL:"=!
- call :judge12 "!txtL!"
- setlocal disableDelayedExpansion
- )
- if defined flag move "Tmp_%%X" Not12
- if not defined flag for /f "usebackq delims=" %%I in ("Tmp_%%X") do (
- for /f "usebackq tokens=1-3* delims=‖" %%a in ('%%I') do (
- if exist "new_%%X" (
- echo %%a‖%%b‖?‖%%d>>"new_%%X"
- ) else echo %%I>"new_%%X"
- )
- )
- )
- pause
- goto :eof
-
- :judge12
- set n=
- set contain=%1
- :lp
- set contain=%contain:*‖="%
- set/a n+=1
- if %n% lss 12 (
- if %contain%=="" set flag=1
- goto :lp
- )
- if not %contain%=="" set flag=1
- goto :eof
- :wordErr
- cd.>"Tmp_%~1"
- for /f "delims= eol=" %%i in ('findstr /v "<<删除>>" %1') do (
- echo+%%i>>"Tmp_%~1"
- )
复制代码
[ 本帖最后由 wxcute 于 2009-2-1 20:26 编辑 ]
作者: leo1984 时间: 2009-2-1 21:35
原帖由 wxcute 于 2009-2-1 20:15 发表
条件总结如下:
一、先删除文本中包含 字串的行;
二、处理一行为 12 个 ‖ 作为分隔符的文本,只要有一行不是 12 个分隔符,就放到一个单独的目录中;
其中不考虑第一行,而且分隔符连续出现时分开算个数
...
前輩我試用您的代碼後
出現如下圖的情況,而處理出來的文本始終保持四~五個
請問是哪裡有錯誤呢?
謝謝
作者: leo1984 时间: 2009-2-1 21:39
原帖由 namejm 于 2009-2-1 19:15 发表
你的文字描述和你提供的文本有一些出入,所谓差之毫厘谬以千里,所以,有几个问题需要确认一下:
1、分隔符号究竟是//还是‖?
2、究竟是要删除含有 <<删除>> 字符串的行还是含有 <<错误>> 的行?
...
1:是‖為分隔符
因為兩岸三地的繁簡編碼不同,我是用big5的繁體中文windows,所以文字上看起來會有差異
2:含有 <<错误>>的行
3:一個‖字符就算一個
[ 本帖最后由 leo1984 于 2009-2-1 22:26 编辑 ]
作者: 9zhmke 时间: 2009-2-2 01:13
高手辈出啊,而且能如此尽心答疑,真是网站幸事
作者: wxcute 时间: 2009-2-2 12:31
代码更新,请测试- @echo off
- if not exist Not12\ md Not12
- for /f "delims=" %%X in ('dir/b *.txt') do (
- set flag=
- call :wordErr "%%X"
- setlocal enableDelayedExpansion
- for /f "usebackq skip=1 tokens=1* delims=!" %%i in ("Tmp_%%X") do (
- set txtL=%%i%%j
- set txtL=!txtL:"=!
- call :judge12 "!txtL!"
- )
- if defined flag move "Tmp_%%X" Not12
- endlocal enableDelayedExpansion
- if exist "Tmp_%%X" for /f "usebackq delims=" %%I in ("Tmp_%%X") do (
- for /f "usebackq tokens=1-3* delims=‖" %%a in ('%%I') do (
- if exist "new_%%X" (
- echo %%a‖%%b‖?‖%%d>>"new_%%X"
- ) else echo %%I>"new_%%X"
- )
- )
- )
- pause
- goto :eof
-
- :judge12
- set n=
- set contain=%1
- :lp
- set contain=%contain:*‖="%
- set/a n+=1
- if %n% lss 12 (
- if %contain%=="" set flag=1
- goto :lp
- )
- if not %contain%=="" set flag=1
- goto :eof
- :wordErr
- cd.>"Tmp_%~1"
- for /f "delims= eol=" %%i in ('findstr /v "<<删除>>" %1') do (
- echo+%%i>>"Tmp_%~1"
- )
复制代码
作者: terse 时间: 2009-2-2 15:14
原帖由 leo1984 于 2009-2-1 16:00 发表
謝謝您的幫忙
不過我剛測試,每個文本的第一行後頭都會多加上∥%b∥%c∥%d這樣一段多餘的字符
請問可以再修正嗎?
去掉 echo %%a‖%%b‖%%c‖%%d ‖%%b‖%%c‖%%d 只留echo %%a
作者: leo1984 时间: 2009-2-2 22:10
原帖由 wxcute 于 2009-2-2 12:31 发表
代码更新,请测试@echo off
if not exist Not12\ md Not12
for /f "delims=" %%X in ('dir/b *.txt') do (
set flag=
call :wordErr "%%X"
setlocal enableDelayedExpansion
for /f "usebackq skip=1 ...
多次麻煩
感謝萬分
我剛測試您代碼,有符合12個∥的文本,也被移到NOT12文件夾裡
請問是為什麼呢? 謝謝!
以下是被移到NOT12文件夾的文本範例
作者: leo1984 时间: 2009-2-2 22:42
原帖由 terse 于 2009-2-2 15:14 发表
去掉 echo %%a‖%%b‖%%c‖%%d ‖%%b‖%%c‖%%d 只留echo %%a
前輩
文本的處理上都沒有問題了
但是有部份文本會多出一行只留下var字符
請問是哪裡錯誤了呢?
再煩請提點,感謝再感謝
[ 本帖最后由 leo1984 于 2009-2-2 22:50 编辑 ]
作者: wxcute 时间: 2009-2-3 19:40
我在 25 楼也有提到,有些 12 个分隔符的被判断错是因为感叹号的缘故。
以下能处理 17 个分开的感叹号。再多的话就得换个思路处理这个符号了。- @echo off
- if not exist Not12\ md Not12
- for /f "delims=" %%X in ('dir/b *.txt') do (
- set flag=
- call :wordErr "%%X"
- setlocal enableDelayedExpansion
- for /f "usebackq skip=1 tokens=1-17* delims=!" %%i in ("Tmp_%%X") do (
- set txtL=%%i%%j%%k%%l%%m%%n%%o%%p%%q%%r%%s%%t%%u%%v%%w%%x%%y%%z
- set txtL=!txtL:"=!
- call :judge12 "!txtL!"
- )
- if defined flag move "Tmp_%%X" Not12
- endlocal enableDelayedExpansion
- if exist "Tmp_%%X" for /f "usebackq delims=" %%I in ("Tmp_%%X") do (
- for /f "usebackq tokens=1-3* delims=‖" %%a in ('%%I') do (
- if exist "new_%%X" (
- echo %%a‖%%b‖?‖%%d>>"new_%%X"
- ) else echo %%I>"new_%%X"
- )
- )
- )
- pause
- goto :eof
-
- :judge12
- set n=
- set contain=%1
- :lp
- set contain=%contain:*‖="%
- set/a n+=1
- if %n% lss 12 (
- if %contain%=="" set flag=1
- goto :lp
- )
- if not %contain%=="" set flag=1
- goto :eof
- :wordErr
- cd.>"Tmp_%~1"
- for /f "delims= eol=" %%i in ('findstr /v "<<删除>>" %1') do (
- echo+%%i>>"Tmp_%~1"
- )
复制代码
[ 本帖最后由 wxcute 于 2009-2-3 19:43 编辑 ]
作者: leo1984 时间: 2009-2-5 07:12
原帖由 wxcute 于 2009-2-3 19:40 发表
我在 25 楼也有提到,有些 12 个分隔符的被判断错是因为感叹号的缘故。
以下能处理 17 个分开的感叹号。再多的话就得换个思路处理这个符号了。@echo off
if not exist Not12\ md Not12
for /f "delims=" %%X in ...
可以用了
感謝版主用心不厭其煩的教導
好心有好報,希望前輩能更上層樓
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |