【问题标题】:MS-DOS batch script: assignment operationMS-DOS 批处理脚本:赋值操作
【发布时间】:2011-06-30 05:00:18
【问题描述】:

我指的是下面的威胁Batch files: How to read a file?。用于从文本文件中逐行检索。我正在使用以下脚本:

@echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ paths.txt"`) do (
    set "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!"
    echo !var!
    ENDLOCAL
)

代码运行良好! !var! 中的值不能分配给任何变量。 :( 我在那里构造,请任何人帮助逐行阅读,我希望分配给某个变量并想要操纵该变量。请帮助解决这种情况。

更新:

@ECHO off

CLS

SET PROJ_DIR=D:\workspace\proj
SET PROMO_DIR=D:\TEST
SET SOURCE_CODE=\Source Code

SETLOCAL DisableDelayedExpansion
for /f %%a in (paths.txt) do (
    SET "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!"
    set FILE_PATH=!var://www.domain.com/path/dir=!
    SET FILE_PATH=!FILE_PATH:/=\!
    SET PROMO_FILE_PATH=!PROMO_DIR!!SOURCE_CODE!!FILE_PATH! 
    FOR %%i IN ("!PROMO_FILE_PATH!") DO SET FOLDER_PATH=%%~dpi
    FOR %%i IN ("!PROMO_FILE_PATH!") DO SET FILE_NAME=%%~nxi
    IF EXIST "!FOLDER_PATH!" GOTO F3
        MKDIR "!FOLDER_PATH!"
    :F3
    IF NOT EXIST "!PROJ_DIR!!FILE_PATH!" GOTO F4
        COPY "!PROJ_DIR!!FILE_PATH!" "!FOLDER_PATH!"
    :F4
        ECHO Cannot find the file under "!PROJ_DIR!!FILE_PATH!"

    ENDLOCAL
)

SET CLOSE_CONFIRM=
SET /P CLOSE_CONFIRM=Press any key to close the window...%=%

paths.txt

//www.domain.com/path/dir/dir1/dir2/file1.txt 
//www.domain.com/path/dir/dir1/dir2/file2.txt 
//www.domain.com/path/dir/dir1/dir2/file3.txt 
//www.domain.com/path/dir/dir1/dir2/file4.txt 
//www.domain.com/path/dir/dir1/dir3/file1.txt

命令输出

        1 file(s) copied.
Cannot find the file under "D:\workspace\proj\dir1\dir2\file1.txt"
        1 file(s) copied.
Cannot find the file under "D:\workspace\proj\dir1\dir2\file2.txt"
Press any key to close the window...

谢谢..

【问题讨论】:

  • 一个简单的set "myVar2=!var!" 应该可以工作,还是您尝试访问endlocal 之后的变量?
  • 它对我不起作用:(我试过"myvar2=!var!"然后echo %myvar2%。但是,它没有打印任何东西。它只是打印ECHO is on。我该怎么办?请帮忙关于这个。谢谢
  • 分配有效,但您的回显失败,因为百分比扩展仅在执行循环之前完成一次。将其更改为echo !myvar2!
  • 您应该显示输入文件和/或将一些调试输出添加到您的代码中,例如echo !var! !FILE_PATH!
  • 好吧,我明白了。我希望你能理解我的一段代码。问题是当一个特定文件夹有超过 2 个文件时。它只能复制两个文件,然后终止进程。这就是我的代码的问题。为什么会这样?

标签: batch-file dos


【解决方案1】:

关键是延迟扩展,始终使用!而不是%扩展括号内的变量。

X 更改为Y 的示例

@echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ paths.txt"`) do (
    set "var=%%a"
    SETLOCAL EnableDelayedExpansion
    set "var=!var:*:=!"
    set "myVar=!var!"
    set "myVar=!myVar:X=Y!"
    echo X replaced with Y =!myVar! 
    ENDLOCAL
)

在您的更新版本中,goto :label 会立即停止 for 循环

最好将其重写为 IF-Blocks

IF NOT EXIST "!FOLDER_PATH!" (
  MKDIR "!FOLDER_PATH!"
)
IF EXIST "!PROJ_DIR!!FILE_PATH!" (
    COPY "!PROJ_DIR!!FILE_PATH!" "!FOLDER_PATH!"
) ELSE
(
    ECHO Cannot find the file under "!PROJ_DIR!!FILE_PATH!"
)

【讨论】:

  • 嗨,jeb,谢谢这对我有用:) 但另一个问题。它从文件中读取 5 行中的 2 行。 :( 为什么会这样?
  • 嗨,jeb,现在更新了!请查看问题...谢谢,它没有读取文件中的所有行。为什么会这样?
  • 非常感谢伙计!实际上,有一个逻辑错误..现在工作:))
【解决方案2】:

这里的其他答案涵盖了此代码中延迟扩展的棘手部分。我想补充一点,您通常可以通过将括号滚动到子例程中来避免大多数延迟扩展问题。

FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ paths.txt"`) do call :HandlePath %%a
goto :eof

================
:HandlePath
set "var=%*"
set "var=%var:*:=%"
echo %var%
goto :eof

我发现这段代码更容易维护,因为每一行都在你期望的时候被解析和执行。

【讨论】:

  • +1,简单问题的好提示,但是这会根据行内容而失败,您不能处理像A difficult text "&"&这样的行,带有百分比扩展或调用参数
【解决方案3】:

如果您想读取每一行并对其进行操作:

SETLOCAL EnableDelayedExpansion
FOR /F "tokens=*" %%a IN (paths.txt) DO (
set var=%%a
ECHO %var%
PAUSE
)
ENDLOCAL

如果您尝试从文件中搜索字符串并对其进行操作:

SETLOCAL EnableDelayedExpansion
FOR /F "tokens=* usebackq" %%a IN (`FIND /I 'string to search for' "C:\folder\paths.txt"`) DO (
set var=%%a
ECHO %var%
PAUSE
)
ENDLOCAL

如果您尝试搜索字符串并操作字符串中的每个单词:

SETLOCAL EnableDelayedExpansion
FOR /F "usebackq tokens=1-999 delims= " %%a IN (`FIND /I 'string to search for' "C:\folder\paths.txt"`) DO (
REM %%a = first word  %%b = second word etc. through the alphabet
set var1=%%a%%b%%c
set var2=%%d
ser var3=%%e
ECHO %var1% %var2% %var3%
PAUSE
)
ENDLOCAL

【讨论】:

  • 它只打印ECHO is off。我不能像var2=!var! 这样分配。
  • 还有一个小问题……您是要在文本文件中搜索特定字符串还是要读取所有行?而且我从未见过!var:*:=!以前使用过... :*:= 应该对变量做什么?
  • 感谢您的及时回复,我正在尝试从文件中逐行读取,我只想操作该行...这就是我想要实现的...
  • 你的回声不能工作,因为 %var1% %var2% 在循环开始之前扩展,你需要在这里延迟扩展或调用技术(非常慢)
【解决方案4】:

这对我有用:

@echo off
SETLOCAL EnableDelayedExpansion

FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ paths.txt"`) do (
set var=%%a
set var=!var:*:=!
echo !var!
)
ENDLOCAL

【讨论】:

  • 我介绍了延迟切换技术,因为在您的代码中,您将丢失所有!,有时还会丢失^
猜你喜欢
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-14
  • 2013-04-24
相关资源
最近更新 更多