中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
作者:
标题: 求一个取文件名变量的 BAT 上一主题 | 下一主题
pzppzp
初级用户





积分 110
发帖 52
注册 2007-7-25
状态 离线
『楼 主』:  求一个取文件名变量的 BAT 使用 LLM 解释/回答一下

功能:
搜索当前目录(不含子目录)的 BIN 文件,如果有两个或两个以上 BIN 文件,则设置:
SET GMAME=ERER
如果没有 BIN 文件,则设置:
SET GMAME=ER
如果只有一个 BIN 文件,则设置:
SET GMAME=BIN文件名 不包含后缀,比如:目录下有一个 DF54.BIN 则:
SET GMAME=DF54

求高手帮忙!


2007-7-25 21:58
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
wudixin96
银牌会员





积分 1928
发帖 931
注册 2007-1-6
状态 离线
『第 2 楼』:   使用 LLM 解释/回答一下

for /f "delims=" %%i in ('dir /b^|find /c "bin"') do (
if %%i geq 2 (
set gmame=erer
) else (
if %%i==1 (set gmame=bin%%~ni) else (set gmame=er)
)
)


没测试,试试?

呵呵,粗心了,少了个)。没把for包好了。

Last edited by wudixin96 on 2007-7-26 at 07:26 AM ]


2007-7-25 22:08
查看资料  发短消息  网志   编辑帖子  回复  引用回复
pzppzp
初级用户





积分 110
发帖 52
注册 2007-7-25
状态 离线
『第 3 楼』:   使用 LLM 解释/回答一下

for /f "delims=" %%i in ('dir /b^|find /c "bin"') do (
if %%i geq 2 (
set gmame=erer
) else (
if %%i==1 (set gmame=bin%%~ni) else (set gmame=er)
)


我把上面六行直接复制到一个BAT文件里,有错误,一运行就退出


2007-7-25 23:15
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
pzppzp
初级用户





积分 110
发帖 52
注册 2007-7-25
状态 离线
『第 4 楼』:   使用 LLM 解释/回答一下

有错:
当只有一个BIN文件时,比如 123.bin
返回 set gmame=bin1
而不是不带后缀的文件名 set gmame=123


2007-7-26 16:07
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
qasa
高级用户




积分 959
发帖 311
注册 2006-4-11
来自 广东-LianJiang
状态 离线
『第 5 楼』:   使用 LLM 解释/回答一下


正确应该是这样的:
for /f "delims=" %%i in ('dir /b^|find /c "bin"') do (
if %%i geq 2 (set gmame=erer) else (
if %%i==1 for /f "delims=" %%j in ('dir /a /b^|find /i "bin"') do (
set gmame=%%~nj) else (set gmame=er)
)
)



   此帖被 +3 点积分     点击查看详情   
评分人:【 wudixin96 分数: +3  时间:2007-7-26 17:31




κχυμγνξοθπρωψιαδλεηφβτζσ┬╀┾┳┞┯┰┱┣┲┳╂╁│├┟┭┠这是什么??这就是我的人生
2007-7-26 17:09
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
ansipeter
中级用户

替身



积分 269
发帖 130
注册 2007-3-23
状态 离线
『第 6 楼』:   使用 LLM 解释/回答一下

在给另外一种解法

@echo off&setlocal enabledelayedexpansion
for /r . %%a in (*.bin) do (
set /a b+=1
if !b! geq 2 set gmame=erer&goto:eof
if !b! equ 1 set "gmame=bin%%~na"
)
if not defined b set gmame=er


   此帖被 +3 点积分     点击查看详情   
评分人:【 wudixin96 分数: +3  时间:2007-7-26 17:31


2007-7-26 17:16
查看资料  发短消息  网志   编辑帖子  回复  引用回复
pzppzp
初级用户





积分 110
发帖 52
注册 2007-7-25
状态 离线
『第 7 楼』:   使用 LLM 解释/回答一下

谢谢,可以了
这里高手真多


2007-7-26 19:25
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
26933062
银牌会员





积分 2268
发帖 879
注册 2006-12-19
状态 离线
『第 8 楼』:   使用 LLM 解释/回答一下

@ECHO OFF
set num=0
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%i in ('dir/b e:\111\*.txt') do (
set var=%%~ni
if exist "%%i" set/a num+=1
)
if %num% equ 0 set GMAME=ER&goto tui
if %num% geq 2 (set GMAME=ERER) else set GMAME=%var%
:tui
echo %GMAME%
pause


2007-7-26 22:52
查看资料  发短消息  网志   编辑帖子  回复  引用回复
pzppzp
初级用户





积分 110
发帖 52
注册 2007-7-25
状态 离线
『第 9 楼』:   使用 LLM 解释/回答一下

按5楼的试了,昨天在XP下,硬盘上,正常
今天刻到启动光盘根目录上,用此光盘启动电脑,从AUTOEXEC.BAT调用运行此BAT出错,显示:
Write protect error writing drive A
难道这个BAT不能在纯DOS下运行或不能在只读盘上运行吗?


2007-7-27 09:42
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
wudixin96
银牌会员





积分 1928
发帖 931
注册 2007-1-6
状态 离线
『第 10 楼』:   使用 LLM 解释/回答一下

还真不知道纯DOS下是否支持for 扩展的。


2007-7-27 09:50
查看资料  发短消息  网志   编辑帖子  回复  引用回复
digger
初级用户

游荡的孤魂



积分 79
发帖 29
注册 2007-4-2
来自 湖南
状态 离线
『第 11 楼』:   使用 LLM 解释/回答一下

  纯DOS下的for是个光杆司令,不支持 /f、/r、/d、/l 开关。


2007-7-27 10:03
查看资料  发短消息  网志   编辑帖子  回复  引用回复
pzppzp
初级用户





积分 110
发帖 52
注册 2007-7-25
状态 离线
『第 12 楼』:   使用 LLM 解释/回答一下

看样子在DOS下没法实现这功能了


2007-7-27 12:00
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
ben
新手上路





积分 12
发帖 6
注册 2007-11-23
状态 离线
『第 13 楼』:   [已使用 LLM 解释]

高手真多啊
LLM 解释

在 2000 年代初期的技术语境下,该帖讨论的问题反映了 Windows NT 命令行扩展与实模式 DOS(Real Mode DOS)之间显著的功能断层。以下是对该讨论涉及的技术细节与错误的深度分析:

1. 命令扩展功能的平台差异

在 Post #8 中,用户提供的代码高度依赖 Windows NT 系列(如 Windows XP/2000)中 CMD.EXE 的增强功能:

  • FOR /F 开关:用于解析文件内容或命令输出,这是 MS-DOS 原生 COMMAND.COM 所不具备的。
  • 路径扩展语法(%%~ni:用于直接提取文件名而不含后缀,这同样是 NT 专有特性。
  • 延迟变量扩展(ENABLEDELAYEDEXPANSION:在循环中动态更新变量值。

在纯 DOS 环境(如 MS-DOS 6.22 或 Windows 98 的实模式)下,FOR 命令仅支持 FOR %%i IN (set) DO command 的基本语法,不支持任何开关。因此,Post #11 提到的“光杆司令”是准确的。

2. "Write protect error writing drive A" 错误原因

Post #9 中用户提到的错误并非由 FOR 命令本身直接导致,而是由 DOS 的 I/O 处理机制引发的:

  • 重定向与管道的临时文件:在实模式 DOS 中,使用管道符(|)或重定向(>)时,系统有时会尝试在当前驱动器或 TEMP/TMP 变量指定的路径创建临时文件。如果脚本运行在只读的光盘(CD-ROM)环境,且当前路径未指向 RAMDISK,就会触发写保护错误。
  • 环境变量空间(Environment Space):若在 AUTOEXEC.BAT 中未通过 SHELL 命令增大环境空间(如 /E:2048),复杂的 SET 操作可能导致溢出。但在该案例中,由于用户在只读光盘根目录运行,系统尝试写入 A 盘(可能是由于某些 DOS 启动盘会将 A: 模拟为可写区或默认交换区)失败。

3. 纯 DOS 环境下的替代方案

要在纯 DOS(无 NT 扩展)下实现“统计文件数并获取去后缀文件名”的功能,通常需要采用以下工程逻辑:

文件数量统计

通过 DIR /B 结合 FIND /C 统计行数,并将结果重定向到文本文件,再通过一些变通方法读取:

dir /b *.bin > filelist.txt
find /c ".bin" filelist.txt > count.txt

提取不带后缀的文件名

这是纯 DOS 批处理最难实现的部分,因为 SET 不支持字符串截取。历史上的标准做法包括:

  1. 临时重命名法:利用 REN 将目标文件复制到 RAMDISK,重命名为无后缀格式,再利用 FOR 循环获取。
  2. 外部工具:使用 Strings.com(常用于 PC-DOS 或由第三方分发)或 Norton Utilities 中的 BE.EXE
  3. DEBUG 脚本:通过汇编一小段程序来处理字符串。

4. 结论与纠正

Post #12 认为“在 DOS 下没法实现”是不准确的。在实模式 DOS 下,实现该逻辑的稳健做法通常是:

  • 确保系统中配置了 RAMDISK(如 RAMDRIVE.SYS),并将所有临时文件和重定向操作指向该驱动器。
  • 使用 IF EXIST 配合循环来判断文件数量。
  • 若只有一个文件,可以通过一个极其隐晦的 FOR 命令变通(例如:FOR %%i IN (*.BIN) DO SET GMAME=%%i),随后利用 REN 结合通配符或专门的解析工具去掉 .BIN 后缀。

此问题的核心矛盾在于用户试图将 32 位 Windows 控制台的高级批处理脚本直接移植到 16 位实模式环境,而忽略了两者命令解释器(CMD.EXE vs COMMAND.COM)在内核实现上的根本区别。



2008-8-27 15:14
查看资料  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: