Board logo

标题: [文本处理] [已解决]批处理for套dir时使用变量扩展为什么不对? [打印本页]

作者: hfgjgx    时间: 2023-11-2 10:57     标题: [已解决]批处理for套dir时使用变量扩展为什么不对?

本帖最后由 hfgjgx 于 2023-11-5 10:33 编辑

执行
  1. [code]@echo off
  2. for /f "delims=" %%i in ('dir /b /ad "C:\Users"') do (
  3. echo "%%~i"
  4. )
复制代码
正确显示了C:\Users下的文件夹名

但一旦用了其他形式的变量扩展,无论是什么形式,echo输出的都是批处理所在的文件路径
例如
  1. @echo off
  2. for /f "delims=" %%i in ('dir /b /ad "C:\Users"') do (
  3. echo "%%~pi"
  4. )
复制代码
显示的是批处理所在的文件路径
  1. @echo off
  2. for /f "delims=" %%i in ('dir /b /ad "C:\Users"') do (
  3. echo "%%~di"
  4. )
复制代码
显示的是批处理所在的盘符
怎么解决,为什么?
作者: ShowCode    时间: 2023-11-2 11:59

回复 1# hfgjgx


    我测试这个代码一切正常。请把你遇到错误的完整代码发出来看看?
作者: 77七    时间: 2023-11-2 14:37

  1. @echo off
  2. >1.txt dir /b /ad "C:\Users"
  3. for /f "delims=" %%i in (1.txt) do (
  4. echo "%%~i"
  5. )
  6. pause
复制代码

分解一下
作者: qixiaobin0715    时间: 2023-11-2 15:27

本帖最后由 qixiaobin0715 于 2023-11-6 14:29 编辑

这种情况就不要把路径写在for里面了:
  1. @echo off
  2. cd /d "C:\Users"
  3. for /f "delims=" %%i in ('dir /b /ad') do echo "%%~i"
复制代码
顶楼的代码运行目录未转换,只是在for循环中指定了要显示的目录中的文件夹名,当前目录还是批处理所在的目录。
需要使用cd命令将当前目录转换为 C:\Users 就不会发生你所说的情况了。
作者: czjt1234    时间: 2023-11-3 14:03

%%~i 是什么,为什么不是 %%i
作者: hfgjgx    时间: 2023-11-3 14:24

回复 2# ShowCode

我因该没讲清楚,我改了一下帖子,请再看一下
作者: hfgjgx    时间: 2023-11-3 14:24

回复 4# qixiaobin0715
我因该没讲清楚,我改了一下帖子,请再看一下
作者: hfgjgx    时间: 2023-11-3 14:25

回复 3# 77七
我因该没讲清楚,我改了一下帖子,请再看一下
作者: hfgjgx    时间: 2023-11-3 14:25

回复 5# czjt1234
参见for /?
作者: qixiaobin0715    时间: 2023-11-3 14:40

回复 7# hfgjgx
我想一开始就知道你什么意思,你运行4楼代码有何问题吗?还有哪点没说清楚?
作者: 77七    时间: 2023-11-3 15:16

如3楼所示,for /f 只是处理dir 的结果,要分开看

比如 你问我姚明身高,我会默认是中国打篮球的姚明,其实你问的是你在国外认识的踢足球的姚明

同样要 扩展 文件的信息, 需要知道它的绝对路径,否则默认是相对路径。(当然如果问姚明姓什么(文件名)除外)
作者: ShowCode    时间: 2023-11-3 15:43

回复 1# hfgjgx


试试我这个思路能否理解:

dir /b /ad "C:\Users" 命令得到的结果集就是普通的字符串,假设结果如下:
Admin
ZhangSan
LiSi

虽然dir命令知道它们是一个一个的文件夹,但是这个结果集交给for命令处理的时候,for命令只知道它们是字符串,不知道它们是文件或文件夹或其它东西,当然更不知道它们在哪个路径下面。

对于for命令来说,其效果在一定程度上类似于:
  1. @echo off
  2. for /f "delims=" %%i in ('echo Admin^&echo ZhangSan^&echo LiSi') do (
  3.     echo "%%~i"
  4. )
复制代码
显而易见,for命令不会知道这些字符串在哪个路径下。这就是顶楼现象的原因。
作者: czjt1234    时间: 2023-11-3 21:42

我用
dir /b /s /ad "C:\Users"
加了个 /s 测试可以
因为加了个 /s 后输出结果天生就是完整路径
对完整路径可以各种扩展
作者: Five66    时间: 2023-11-4 00:15

for语句的变量拓展其实是字符串匹配
例如
%~i 是匹配变量 i 开头跟结尾0个或1个双引号之间的内容
%~di 是匹配开头1个字符跟1个英文冒号,匹配不了就使用当前路径拼接 i 后再次匹配(???)
%~xi 是去掉变量 i 结尾的空格和点号,匹配最后一个英文点号到结尾之间的内容
%~ti 是用变量 i 的内容匹配文件名,并获取对应的时间
作者: /zhqsystem/zhq    时间: 2023-11-4 23:13

本帖最后由 /zhqsystem/zhq 于 2023-11-4 23:22 编辑

因为你dir没加/s参数,只会获取文件夹名称,扩展路径也只会扩展到批处理默认的%cd%路径,需要二次加入dir的文件夹完整路径.示例:"C:\Users\%%~nxi[也可以用%%i和%%~i但不能使用%%~ni该值只适用无英文点的环境]"完整写法是
1,
cd/d C:\Users
for /f "delims=" %%i in ('dir/ad/b "%cd%\*.*"') do echo,%cd%\%%~nxi
2,

for /f "delims=" %%i in ('dir/ad/b "C:\Users\*.*"') do for /f "delims=" %%j in ("C:\Users\%%~nxi")do echo,%%~fj&&rem特别说明如果%%i不需要引用这里的%%j全部可选为%%i的参数,只有需要时候不能改变




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