Board logo

标题: [文本处理] 批处理:if-变量值输出到文本的问题 [打印本页]

作者: WBATW    时间: 2022-10-21 22:43     标题: 批处理:if-变量值输出到文本的问题

请专家指引一下哦
①代码运行echo;"!tet:~0,2!"显示:“C:”,我该如何补全“ if "!tet!"=="!tet~0,2!" echo %%i ”,才能打印输出到txt文本呢?
②如果我要保留原文件的空行、格式不变,本代码又该怎么修改?
你的任何帮助对我都是有用的。谢谢!
代码如下:
setlocal enabledelayedexpansion
for /f "delims=" %%i in ('dir /b /a-d /s *.txt') do (
set "tet=%%i"
if "!tet!"=="!tet:~0,2!" echo %%i >> 3.txt
echo;"!tet:~0,2!"
)
pause
作者: hfxiang    时间: 2022-10-22 10:52

俺好像没看明白楼主的真实需要
作者: fzp070    时间: 2022-10-22 12:52

回复 2# hfxiang

确实感觉挺怪的,我也没看懂,还有些疑惑.

楼主开头说的:
代码运行echo;"!tet:~0,2!"显示:“C:”,那如下代码怎么会相等?
另外就算不看这句话,单看代码 !tet!获取到的是批处理所在目录 所有.txt文档的全路径,如下代码【 "!tet!"=="!tet:~0,2!"】也不可能相等吧!
  1. if "!tet!"=="!tet:~0,2!"
复制代码

作者: fzp070    时间: 2022-10-22 13:06

回复 3# fzp070

@WBATW
楼主得好好说说自己的需求,你目前的代码批处理即使在C盘运行,结果也是不可能相等。
目前代码中获取到的  "!tet!" 举例是 "C:\1.txt" ,而"!tet:~0,2!"就是 "C:" ,这两者就不可能相等啊!
作者: 77七    时间: 2022-10-22 13:19

估计是提取文件名前两个字符相同的文本的内容,输出到文本3?回复 3# fzp070
作者: fzp070    时间: 2022-10-22 14:16

回复 5# 77七

应该不是,这个批处理获取到的文本文件都是同一个盘符的,即 提取文件名前两个字符 都是一样的。如果是这个想法,没必要这样判断啊。
作者: WBATW    时间: 2022-10-22 20:27

回复 6# fzp070
作者: WBATW    时间: 2022-10-22 21:14

回复 2# hfxiang

非常感谢各位专家!
我重新描述一下:
   本批处理代码要解决的问题是:提取目录子目录下(文件夹)所有txt文本文件内容中少于3个字符的行输出到3.txt。
   我把('dir /b /a-d /s *.txt')它改为1.txt单个文件,运行代码可以获取小于3字符的所有行到3.txt。但是批量处理就不行了,我用添加 echo;"!tet:~0,2!" 调试查看在cmd窗口显示:“C:”,有几个文件就显示几个/每行一个“C:”,我想问题应该出在 if....句,但是我不会处理了,特向批处理专家请教,分享大家的好办法。
   第②个问题我想是这样的:如果不是提取而直接批量删除小于3个字符的行,那么如何保留各个文本原格式不变,比如原来的空行、空格等保留不变
作者: WBATW    时间: 2022-10-22 21:22

本帖最后由 WBATW 于 2022-10-22 21:23 编辑

回复 4# fzp070

我的重新描述放在 8楼(回复 2# hfxiang)烦请专家看看哦
作者: WBATW    时间: 2022-10-22 21:25

回复 3# fzp070

我的重新描述放在 8楼(回复 2# hfxiang)烦请专家看看哦
作者: fzp070    时间: 2022-10-22 21:40

回复 10# WBATW

呃,我只是个初学者,你的问题我还没太搞懂。帮你呼高手@WHY
作者: fzp070    时间: 2022-10-22 22:56

本帖最后由 fzp070 于 2022-10-22 22:59 编辑

回复 8# WBATW


    如下代码是提取a.txt文本文件内容中少于3个字符的行内容 输出到3.txt,保存ANSI格式,确保文本也是ANSI格式。
没有试所有目录子目录下(文件夹)所有文档,所有文档感觉挺复杂的,待高人。
  1. @echo off&&setlocal enabledelayedexpansion
  2. for /f "tokens=1 delims=" %%a in (a.txt) do (
  3.     set tempa=%%a
  4.         if "!tempa:~3,1!"=="" echo %%a>>3.txt
  5. )
  6. exit
复制代码
第②个问题我想是这样的:如果不是提取而直接批量删除小于3个字符的行,那么如何保留各个文本原格式不变,比如原来的空行、空格等保留不变。==删除小于3个字符的行,仅针对a.txt一个文本
  1. @echo off&&setlocal enabledelayedexpansion
  2. for /f "tokens=1 delims=" %%a in (a.txt) do (
  3.     set tempa=%%a
  4.         if not "!tempa:~2,1!"=="" echo %%a>>3.txt
  5. )
  6. exit
复制代码

作者: fzp070    时间: 2022-10-22 23:42

回复 10# WBATW

提取批处理所在目录的多个文本,少于3位的行内容,保存在文本所在目录,和文本同名-1.txt的文档内(也可以保存在同一个文档内,自己改下)。
  1. @echo off&setlocal EnableDelayedExpansion
  2. set j=1
  3. for /f "delims=" %%i in ('dir /b /a-d /s *.txt') do (
  4. set "tet=%%i"
  5. echo 正在处理文本!j!
  6. for /f "tokens=1 delims=" %%a in ('findstr .* "!tet!"') do (
  7.     set tempa=%%a
  8.         if "!tempa:~2,1!"=="" echo %%a>>!tet!-1.txt
  9. )
  10. set /a j+=1
  11. )
  12. exit
复制代码

作者: qixiaobin0715    时间: 2022-10-23 08:22

本帖最后由 qixiaobin0715 于 2022-10-24 16:05 编辑

回复 8# WBATW
可以不用if而用findstr(感谢fzp070测试,补充说明:只能精确处理ASCII字符,如果存在中文等其它双字节字符,可能会有部分疏漏)
第一个问题:
  1. @echo off
  2. (for /f "tokens=1* delims=:" %%i in ('findstr /s /r /v "..." *.txt') do echo,%%j)>3.txt
复制代码
第二个问题:
  1. @echo off
  2. for /f "delims=" %%i in ('dir /s /b /a-d *.txt') do (
  3. findstr /r /x /v ". .." "%%i">temp.log
  4. move "temp.log" "%%i"
  5. )
复制代码
以上代码保存为ANSI编码,bat文件放在主目录下。未经测试,请备份好源文件,以免出现问题。
作者: Batcher    时间: 2022-10-23 09:52

回复 8# WBATW


建议你编辑顶楼的帖子内容描述具体需求。

如果需要上传文件,可以用阿里云盘或百度网盘。

如果需要上传截图,可以找个图床,例如:
http://bbs.bathome.net/thread-60985-1-1.html
作者: fzp070    时间: 2022-10-23 14:57

回复 14# qixiaobin0715
  
     很精简,刚试了下第一个的代码,发现有漏,文本内容如下:
  1. 12345
  2. 12345w
  3. 12345678
  4. 1234
  5. 123
  6. 中文
  7. 中文字
  8. 中国文字
  9. 1
  10. 2
  11. 3
复制代码
运行结果如下:
  1. 1
  2. 2
复制代码
应该要的结果是(提取少于3个字符的行内容):
  1. 中文
  2. 1
  3. 2
  4. 3
复制代码

作者: hfxiang    时间: 2022-10-23 16:00

回复 8# WBATW


   
对于文本处置,俺比较喜欢用gawk ( http://bcn.bathome.net/tool/4.1.0/gawk.exe
对于第1个问题
  1. gawk "length($0)<3&&NF" *.txt>3.txt
复制代码
对于第2个问题
  1. gawk "length($0)=>3||NF==0" *.txt>4.txt
复制代码
注意:txt文件应该为ANSI编码格式,如果是UFT-8格式,需用Ruby-3.1.2-1提供的gawk处置
作者: fzp070    时间: 2022-10-23 19:46

回复 17# hfxiang

试了下,第一个代码运行正常。第2个代码运行报错。
  1. gawk: cmd. line:1: length($0)=>3||NF==0
  2. gawk: cmd. line:1:           ^ syntax error
  3. 请按任意键继续. . .
复制代码

作者: hfxiang    时间: 2022-10-24 07:52

回复 18# fzp070


   
俺的电脑测试正常,你试试下面这个
  1. gawk "(length($0)>=3)||(NF==0)" *.txt>4.txt
复制代码

作者: qixiaobin0715    时间: 2022-10-24 09:09

本帖最后由 qixiaobin0715 于 2022-10-24 14:50 编辑

回复 16# fzp070
还真是这么回事,findstr中的一般表达式对非ASCII字符好像不怎么友好,1个点号代表一个字节,而1个中文字符是2个字节,所以就出现了上述问题,如果是ASCII字符就没问题。至于例子中的最后一行3未显示出来,我想可能是因为文本最后一行未加回车换行。
第2个代码也会有同样的情况出现。已在原楼层作了补充说明。
作者: WBATW    时间: 2022-10-24 17:15

回复 13# fzp070

代码测试成功运行,功能实现每个文件独立输出到文本,也可以输出到一个文件

,感觉效果很好,还写了3个方案,真诚感谢你的辛苦付出,谢谢!关于if...和

dir及findstr的关系还存疑惑,需继续向专家们学习!

作者: fzp070    时间: 2022-10-24 17:18

回复 19# hfxiang

这个正常,感谢解答和分享!
作者: WBATW    时间: 2022-10-24 17:24

回复 14# qixiaobin0715

首先,非常感谢你列举了两个问题的代码。辛苦了!
其次,请问一下专家:运行代码的结果出现了以下情况:
中间行为回车符空行的会提取出来;纯数字字母的可以正常提取到而纯汉字的却

提取不到(同样是2个字符如“2进”和“二进”。好像与字符的字节大小有关)

、或者有少数提取(数字开头的容易获取到哦)。主要是中文汉字,代码2的情况

好于代码1,特别是能在原文件中直接去除字符的方法很好。请教专家是什么情况

,是否可以通过修改代码能解决。再次感谢!
作者: fzp070    时间: 2022-10-24 17:24

回复 20# qixiaobin0715


    了解了,谢谢解答!
作者: WBATW    时间: 2022-10-24 17:46

回复 17# hfxiang

非常感谢再次提出解决和分析方案。在此真诚感谢各位

专家的指教,谢谢!

谢谢大家的热情和参与!
作者: WBATW    时间: 2022-10-24 17:50

回复 20# qixiaobin0715
非常感谢你的热情,你也发现了问题
作者: WBATW    时间: 2022-10-24 18:30

回复 15# Batcher


    好的,谢谢提示!
作者: fzp070    时间: 2022-10-24 19:14

回复 21# WBATW


    客气了,相互学习!
    13楼的代码只提供了[提取少于3个字符数的行内容]。
如下代码是去除少于3个字符的行内容,并保存至文本所在目录,和文本相同名-1.txt文档内(也可以保存在同一个文档内,自己改下)。
  1. @echo off&setlocal EnableDelayedExpansion
  2. set j=1
  3. ::获取批处理目录及子目录所有txt文本
  4. for /f "delims=" %%i in ('dir /b /a-d /s *.txt') do (
  5. set "tet=%%i"
  6. rem 提取文本路径、文件名、文件后缀
  7. for %%I in ("!tet!") do (set fp=%%~dpI&set fn=%%~nI&set fx=%%~xI)
  8. echo 正在处理文本!j!:!fn!!fx!
  9. rem 对文本每行进行字符数判断,保留3个字符及以上的行内容,输出至文本同名-1.txt的文档内
  10. for /f "tokens=1 delims=" %%a in ('findstr .* "!tet!"') do (
  11.     set tempa=%%a
  12.         if not "!tempa:~2,1!"=="" echo %%a>>"!fp!!fn!-1!fx!"
  13. )
  14. set /a j+=1
  15. )
  16. echo 运行完成
  17. pause
  18. exit
复制代码

作者: WBATW    时间: 2022-10-25 15:36

本帖最后由 WBATW 于 2022-10-25 15:39 编辑

回复 28# fzp070
谦虚了____
还是要感谢你的回复!
    首先肯定你的思路开阔,考虑细腻,代码注释说明,条理清楚近逼完美,惯习以常,毕慧聚自成,盛器也!
(我们技术人机械人一般都,说1不2,看上去简练精准没有多余的“废话”而很有知识,但却丢失了另外一样重要的东西__沟通交流的文化。就像是有骨架没有血肉,就会远离对方的亲近感而丢失沟通交流的机会,代码是知识注释是文化....哈哈哈...扯远了)书归正传:
    代码测试一次成功,还有就是输出的新文件没有保留原格式,会把原来的空行去除了,可否通过修改代码保留原来格式;你这代码提示我想起一个新功能:某些特定的多个字符和符号比如:“本目录”“@)”“25”等等之类也提取到输出文件。这样的话可以防止虽然是小于3字符但是又需要保留的不被去除。谢谢!
作者: qixiaobin0715    时间: 2022-10-25 16:06

回复 29# WBATW
可参考这个帖子,对28楼代码进行修改:
http://bbs.bathome.net/viewthrea ... D%D1%F9%CA%E4%B3%F6
作者: qixiaobin0715    时间: 2022-10-26 08:11

本帖最后由 qixiaobin0715 于 2022-10-26 10:34 编辑

回复 29# WBATW
你所谓的新功能实现起来应当不难,只需要预先设置几个有关变量,然后读取文本内容时加以判断即可。“本目录”是3个字符,本来就不会被排除。
作者: qixiaobin0715    时间: 2022-10-26 09:40

回复 29# WBATW
应用上面链接帖子中第2个代码,保留文本中字符为“@)”“25”的行及空行。代码保存为ANSI编码:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set /a _@)=1,_25=1
  4. for /f "delims=" %%i in ('dir /s /b /a-d *.txt') do (
  5.     (for /f "tokens=1* delims=:" %%a in ('findstr /n .* "%%i"') do (
  6.         if "!_%%b!"=="1" (
  7.             echo,%%b
  8.         ) else if "%%b"=="" (
  9.             echo,
  10.         ) else (
  11.             set str=%%b
  12.             if not "!str:~2!"=="" echo,%%b
  13.         )
  14.     ))>temp.log
  15.     move /y "temp.log" "%%i"
  16. )
  17. pause
复制代码
代码未经测试,请自行测试,有问题再讨论。
作者: WBATW    时间: 2022-10-27 22:09

回复 32# qixiaobin0715

恭喜恭喜,这个思路很好,测试基本成功!
辛苦了,qixiaobin0715 !
    测试过程发现:
    代码设置字符“@)”为中文时,测试文件中有英文“@)”和中文“@)”字符,中文“@)”可以成功获取(英文的“@)”获取不到);
    代码设置字符“@)”为英文时,此时,英文字符获取不到、中文的也获取不到。如何修改代码来解决这个难题呢,另外,回车换行的空行保留了而有空格的空行(Tab空行)会被去除掉,可否挽留呢!还要费专家心思了,谢谢!
作者: qixiaobin0715    时间: 2022-10-28 08:39

本帖最后由 qixiaobin0715 于 2022-10-28 11:45 编辑

你还是没把问题说清楚,最好能将 要保留的少于3个字符的所有特例列个清单(要真实),便于帮助你的人测试用。
1.你可以把清单存入文本文件,发到网盘上;
2.还可以把清单直接发到帖子上,不要“..”  “.”  “..”这种,也不要这种:
..
.
..
需要别人给你的代码那样:
  1. ..
  2. .
  3. ..
复制代码
3.也可以采用最直接的办法,对32楼代码进行修改:
a)去掉第3行的预设变量;
b)修改判断语句,穷尽你所要保留的各种可能(使用多个else if这种形式):
  1. if ... (
  2. ...
  3. ) else if...(
  4. ...
  5. ) else if...(
  6. ...
  7. ) else (
  8. ...
  9. )
复制代码

作者: WBATW    时间: 2022-11-1 14:16

本帖最后由 WBATW 于 2022-11-1 14:24 编辑

回复 34# qixiaobin0715
哦~
好的,谢谢!
    也许是我描述过细反而不利于理解。
其实就是英文半角状态的“@)”字符、“)”【不包括引号】括号字符获取不到。最好保留所有的空行。【顺便说明:中文字符状态下效果非常棒】。
    这是我用32楼代码的测试文件:1.txt,请批处理专家qixiaobin0715 试测,谢谢!
------------------------------------
我的测试字符为英文:
25
@)
)
第4行空格空行
最好是能够保留原文件原有的空行。
(32楼代码中的变量需要修改或者增加一个_)=1)
-----------------------------------
作者: qixiaobin0715    时间: 2022-11-1 14:28

回复 35# WBATW
难道我在34楼还没说清楚?
如果自己要修改代码,请看第3点;
如果想要我帮你修改代码,请再仔细看看第1、2点。
作者: qixiaobin0715    时间: 2022-11-1 15:10

本帖最后由 qixiaobin0715 于 2022-11-1 15:12 编辑

回复 35# WBATW
根据你的描述,我帮你列一下要保留的清单,你看看是不是这样,共10种情况:
  1. 25
  2.   
  3. @)
  4. @)
  5. )
复制代码

作者: WBATW    时间: 2022-11-3 00:23

回复 37# qixiaobin0715
非常感谢你列出的清单详细,中英文都包括了,完全正确。不知道代码有难度没有。
作者: qixiaobin0715    时间: 2022-11-3 10:11

回复 38# WBATW
  1. @echo off
  2. set var="25" "" " " "  " " " " " "@)" ")" "@)" ")"
  3. for %%i in (%var%) do set _%%i=true
  4. for /f "delims=" %%i in ('dir /s /b /a-d *.txt') do (
  5.     (for /f "tokens=1* delims=:" %%a in ('findstr /n .* "%%i"') do (
  6.         if defined _"%%b" (
  7.             echo,%%b
  8.         ) else (
  9.             set str=%%b
  10.             setlocal enabledelayedexpansion
  11.             if not "!str:~2!"=="" echo,%%b
  12.             endlocal
  13.         )
  14.     ))>temp.log
  15.     move /y "temp.log" "%%i"
  16. )
  17. pause
复制代码
bat文件保存为ANSI编码,请自行测试。
作者: WBATW    时间: 2022-11-16 18:26

回复 39# qixiaobin0715
感谢你的回复!
    感谢专家,智慧无量,笔下代码新颖,成功运行。也许在代码程序家的眼里是一小酌,但却彰显了批处理之家成员的品味,真诚赞贺!
谢谢!




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