Board logo

标题: [已结]如何全盘查找某文件并把它的路径加到环境变量中 [打印本页]

作者: wentimao     时间: 2006-6-4 06:49    标题: [已结]如何全盘查找某文件并把它的路径加到环境变量中

如何全盘查找某文件,满足一个条件就停止搜索,并把它的路径加到环境变量path中

[ Last edited by willsort on 2006-6-14 at 17:41 ]
作者: namejm     时间: 2006-6-6 13:51
  请问你的"满足一个条件就停止搜索"的"一个条件"是什么意思?
  按照一般的理解,就是找到第一个文件就停止查找。
  但是查询的顺序不一样(是按照盘符顺序的C D E……?还是先在本目录下查找再在当前盘下查找再然后才是C D E……的顺序?),导致找到"第一个文件"的"第一个"就不一样。
  姑且认为是按照C D E……盘符的顺序查找,找到第一个文件之后就停止搜索,要实现你的要求,以下代码可能有所帮助:
@echo off
:: 把按照盘符顺序查到的第一个指定文件加入到查询路径中去
:: 因为dir命令不能查询本脚本程序所在盘符下的所有文件
:: 所以要用cd\返回到根目录下以实现全盘查询
cd\
del list.txt>nul 2>nul
for %%i in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
dir /a /b /s %%i:test.txt>list.txt 2>nul && goto :add
)
echo 不存在该文件
pause
:add
for /f %%i in (list.txt) do path=%path%;%%i
del list.txt>nul 2>nul
path
pause

作者: willsort     时间: 2006-6-6 18:53
Re namejm:

      兄的代码大致是有效的,但也存在着一些问题:

      1、%%i:之后应该紧随一个表示根目录的“\”,否则dir将以当前目录为起始路径搜索;你的cd\只能保证当前盘是以根目录为起始路径,而无法保证其它磁盘;而你所提到的“dir命令不能查询本脚本程序所在盘符下的所有文件”则是错误的。

      2、:add之前应加一句goto :eof,否则流程会出现问题;

      3、:add之下的for语句,会使位于同一磁盘的多个目标路径中最后匹配的一个添加到%path%中;

      4、dir /s使用的是深度优先算法,这在目标存在于一些较浅的路径时,搜索效率降低;当然,现在还没有太好的广度优先算法的现有工具或命令可以使用,用批处理自己编写,具有一定的复杂度,效率上也不一定更加优秀。
作者: wentimao     时间: 2006-6-6 22:17
在do里加一句cd%%i:\ 2>nul
然后再dir就可以了吧

[ Last edited by wentimao on 2006-6-6 at 22:30 ]
作者: namejm     时间: 2006-6-6 23:07
Re willsort:

  1、%%i:之后应该紧随一个表示根目录的“\”,否则dir将以当前目录为起始路径搜索;你的cd\只能保证当前盘是以根目录为起始路径,而无法保证其它磁盘;而你所提到的“dir命令不能查询本脚本程序所在盘符下的所有文件”则是错误的。
  ——看到楼主以前说过,dir c:test.txt和dir c:\test.txt是有区别的,当时没有仔细验证,以为dir /s c:test.txt就是全盘查找语句,所以用上了cd\语句,还得出了“dir命令不能查询本脚本程序所在盘符下的所有文件”的错误结论。看来自己粗心了。
      2、:add之前应加一句goto :eof,否则流程会出现问题;
  ——恩,版主是个细心之人。写代码太过匆忙,居然把这个地方漏了,再次发现自己是个马大哈。
      3、:add之下的for语句,会使位于同一磁盘的多个目标路径中最后匹配的一个添加到%path%中;
  ——当初测试的时候,只在C盘根目录下放了test.txt,没有在更多的地方放置测试文件,又是一大疏漏,直接导致了这段代码是个失败的示例。再次测试的时候,发现了一个细节:如果test.txt放在一个带空格的目录下的话,path命令将不能正确执行。 
 
  修改后的代码如下,但是暂时没法解决path不能执行带空格的路径的问题:
@echo off
:: 把按照盘符顺序查到的第一个指定文件加入到查询路径中去
:: 当路径带空格时不能正确执行
del list.txt>nul 2>nul
for %%i in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
    dir /a /b /s %%i:\test.txt>list.txt 2>nul && goto :add
)
echo 不存在该文件
pause && goto :eof
:add
for /f %%i in (list.txt) do (
    find "test.txt" list.txt>nul 2>nul && path=%path%;%%i && goto end
)
goto :eof
:end
del list.txt>nul 2>nul
path
pause
[ Last edited by namejm on 2006-6-6 at 23:12 ]
作者: hyuanqing     时间: 2006-6-6 23:35    标题: 麻烦各位指点解释一下这个批处理

@echo off
:: 把按照盘符顺序查到的第一个指定文件加入到查询路径中去
:: 当路径带空格时不能正确执行
del list.txt>nul 2>nul
for %%i in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
    dir /a /b /s %%i:\test.txt>list.txt 2>nul && goto :add
)
echo 不存在该文件
pause && goto :eof
:add
for /f %%i in (list.txt) do (
    find "test.txt" list.txt>nul 2>nul && path=%path%;%%i && goto end
)
goto :eof
:end
del list.txt>nul 2>nul
path
pause
如何全盘查找某文件,满足一个条件就停止搜索,并把它的路径加到环境变量path中。这是刚看的一段代码,其中有几个地方不明白,麻烦各位指点一下!谢谢
del list.txt>nul 2>nul    这里是什么意思?(为什么用del呢?还有>nul 2>nul这是什么用法?)
pause && goto :eof 这里也不明白,以前写直接用个标号就好了,这里为什么要用:eof呢?两个&&代表什么意思呢?
path=%path% (一直都不明白的这两个百分号的用法)
小弟刚刚接触批处,还很多不懂的地方,请多多指教:)
作者: willsort     时间: 2006-6-6 23:38
Re namejm:

      不知道你最近的测试过程,不过单从代码上看,使用find似乎并不能解决含空格目录的问题,反而增加了冗余代码。这里应该使用"delims="参数。
@echo off
for %%i in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
    (for /f "delims=" %%p in ('dir /a /b /s %%i:\test.txt') do (
        set path=%path%;%%p&&goto :eof
    )) 2>nul
)
echo 不存在该文件
pause && goto :eof

作者: willsort     时间: 2006-6-6 23:44

───────────────── 版务记录 ─────────────────
执行:Will Sort
操作:合并主题 {21070}麻烦各位指点解释一下这个批处理 -> 6楼
说明:操作主题与本主题存在上下文的直接联系
处罚:因属论坛新人,不予积分处罚
提示:请访问 {7326}论坛新手必读,所有人的基本行为准则[转帖]
───────────────── 版务记录 ─────────────────

作者: namejm     时间: 2006-6-7 00:28
Re willsort:

  在以前的印象中,一直以为用for嵌套的时候对变量的引用很麻烦,所以一直不敢尝试用for嵌套,现在看了版主的代码,简洁而实用,PF。——for真是太强大了。
作者: namejm     时间: 2006-6-7 00:41
Re hyuanqing:

  del list.txt>nul 2>nul    这里是什么意思?(为什么用del呢?还有>nul 2>nul这是什么用法?)
  ——这里用了del,是为了防止以下语句输出到list.txt的时候会在list.txt内容的后面追加内容,但是考虑到下面的语句中用的是>而不是>>,这句应该是多余的。>nul 2>nul意思是无论语句执行成功与否,都不在屏幕上显示执行结果。
  pause && goto :eof 这里也不明白,以前写直接用个标号就好了,这里为什么要用:eof呢?两个&&代表什么意思呢?
  ——goto :eof意思是直接跳到批处理程序的结尾,在一般情况下相当于exit命令,一个&的意思是同时执行&连接的两条语句,而两个&则表示如果&&的前一句语句执行成功,则执行&&之后的语句。另:如果用||,则表示如果||的前一句语句执行失败,则执行||之后的语句。
  path=%path% (一直都不明白的这两个百分号的用法)
  ——百分号的意思是引用前面定义过的变量。这应该属于批处理语法的基础了。

[ Last edited by namejm on 2006-6-7 at 16:24 ]
作者: Climbing     时间: 2006-6-8 01:29
我觉得你们的代码虽然一个比一个完善,但都忽略了一个重要的问题,那就是,你们所搜索到的路径中都包括文件名本身,而这个文件名是不应该被放到搜索路径path中的,否则好象搜索路径就失去了意义。
@echo off
for %%i in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
    (for /f "delims=" %%P in ('dir /a /b /s %%i:\test.txt') do (
        set path=%path%;%%~dpsP&&goto :eof
    )) 2>nul
)
echo 不存在该文件
pause && goto :eof
不过这个批处理好象最终的结果还是将找到的最后一个路径加入了PATH,看来必要时需要启用延迟环境变量扩展。
作者: willsort     时间: 2006-6-8 01:41
Re Climbing:

      路径中带有文件名确实是个问题,修改代码前也曾注意到它,只是修改中将它忘记了,而最后没有测试修改代码。

      至于将最后路径加入 %path% 则难于理解,&&goto :eof 应该没有什么太大的问题。
作者: Climbing     时间: 2006-6-8 10:22
Re Wil:

不好意思,是我理解错了,我原来以为是将每个搜索到的路径都加入PATH,原来只是将找到的第一个加入。
作者: regvip2008     时间: 2007-10-28 14:26
楼上各位高手的言论,让我等新手受益匪浅!
作者: yptd     时间: 2008-5-31 01:58
菜鸟东拼起来的P,指点下~~~~~~

  Quote:
@echo off
setlocal enabledelayedexpansion
for %%i in (D E F G H I) do (
    (for /f "delims=" %%p in ('dir /a /b /s %%i:\1.rar') do (
        set var=%%p&&goto :loop
    )) 2>nul
)

:loop

set "route=%var%"
set layers_discard=1
if "%route:~-1%"=="\" set "route=%route:~0,-1%"
for /l %%i in (1,1,%layers_discard%) do call :intercept "%%route%%"
:end
echo "%route%"
pause
goto :eof
:intercept
for /f "delims=" %%i in (%1) do set "route=%%~dpi"
if "%route:~-2,1%"==":" (goto end) else set "route=%route:~0,-1%"
goto :eof