在一個復雜的批處理檔案中,我想讀入帶有路徑的檔案,除其他外,將它們一個接一個地讀入一個由空格分隔的變數。
到目前為止,這適用于以下代碼 - 但前提是路徑不包含感嘆號。
即使使用 setlocal 命令(enabledelayedexpansion / disabledelayedexpansion)我也沒有成功處理感嘆號。
這里有人對這個問題有一個聰明的主意嗎?
以下示例批處理在當前目錄中創建一個文本檔案,然后在 for /F 回圈中讀取它。最后,文本檔案中的所有三個路徑都應該在變數 %Output% 中。但是帶有感嘆號。
@echo off
setlocal enabledelayedexpansion
echo This is an example^^! > "textfile.txt"
echo This is a second example^^! >> "textfile.txt"
echo And this line have an ^^! exclamation mark in the middle >> "textfile.txt"
for /F "usebackq tokens=* delims=" %%a in (textfile.txt) do (
set "Record=%%a"
set "Output=!Output!!Record! - "
)
)
echo %Output%
echo !Output!
endlocal
輸出是這樣的:
This is an example - This is a second example - And this line have an exclamation mark in the middle
但應該是這樣的:
This is an example! - This is a second example! - And this line have an ! exclamation mark in the middle
uj5u.com熱心網友回復:
建議不要對處理檔案和目錄、文本檔案中的行、批處理檔案本身未定義的字串或從執行程式或命令列捕獲的輸出使用延遲變數擴展。如果由于某些原因需要在FOR回圈中使用延遲變數擴展,則應首先將要處理的檔案/目錄名稱、行或字串分配給環境變數,同時禁用延遲擴展,然后再啟用FOR回圈內的延遲擴展臨時。
這是一個批處理檔案演示,可以簡單地從命令提示符視窗中運行,也可以通過雙擊批處理檔案來運行。它在臨時檔案的目錄中創建了幾個用于演示的檔案,但在退出之前將它們全部洗掉。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
echo This is an example!> "%TEMP%\TextFile.tmp"
echo This is a second example!>> "%TEMP%\TextFile.tmp"
echo And this line has an exclamation mark ! in the middle.>> "%TEMP%\TextFile.tmp"
set "Output="
(for /F usebackq^ delims^=^ eol^= %%I in ("%TEMP%\TextFile.tmp") do call :ConcatenateLines "%%I") & goto ContinueDemo
:ConcatenateLines
set "Output=%Output% - %~1" & goto :EOF
:ContinueDemo
cls
echo/
echo All lines concatenated are:
echo/
echo %Output:~3%
set "Output="
del "%TEMP%\TextFile.tmp"
echo File with name ".Linux hidden file!">"%TEMP%\.Linux hidden file!"
echo File with name "A simple test!">"%TEMP%\A simple test!"
echo File with name " 100%% Development & 'Test' (!).tmp">"%TEMP%\ 100%% Development & 'Test(!)'.tmp"
echo/
echo Files with ! are:
echo/
for /F "eol=| tokens=* delims=" %%I in ('dir "%TEMP%\*!*" /A-D /B /ON 2^>nul') do (
set "NameFile=%%I"
set "FileName=%%~nI"
set "FileExtension=%%~xI"
set "FullName=%TEMP%\%%I"
setlocal EnableDelayedExpansion
if defined FileName (
if defined FileExtension (
echo File with ext. !FileExtension:~1!: !NameFile!
) else (
echo Extensionless file: !NameFile!
)
) else echo Extensionless file: !NameFile!
del "!FullName!"
endlocal
)
endlocal
echo/
@setlocal EnableExtensions EnableDelayedExpansion & for /F "tokens=1,2" %%G in ("!CMDCMDLINE!") do @endlocal & if /I "%%~nG" == "cmd" if /I "%%~H" == "/c" set /P "=Press any key to exit the demo . . . "<nul & pause >nul
這個批處理檔案的輸出是:
All lines concatenated are:
This is an example! - This is a second example! - And this line has an exclamation mark ! in the middle.
Files with ! are:
File with ext. tmp: 100% Development & 'Test(!)'.tmp
Extensionless file: .Linux hidden file!
Extensionless file: A simple test!
具有連接行的文本檔案示例使用從FOR回圈中呼叫的子例程來處理文本檔案中的行。此處使用的語法是通過使子例程盡可能靠近FOR命令列來獲得最大性能。如果FOR回圈必須處理數百甚至數千個專案,這一點很重要。
在將當前處理的檔案的所有部分分配給環境變數之后,處理檔案名的示例在FOR回圈內啟用和禁用延遲擴展。在處理數千個檔案之前減少環境變數串列可能很有用,以便在使用此方法時獲得更好的性能。
Magoo 的答案中顯示了另一種方法,使用命令CALL來獲取命令列,其中參考的環境變數(重新)在回圈內被第二次決議。我過去也經常使用這種方法,但現在不要那樣做,因為它不是故障安全且效率不高。call set導致在cmd.exe當前目錄中搜索,然后在環境變數的所有目錄中搜索PATH具有名稱set和檔案擴展名的檔案 environment variable PATHEXT。因此,它會在FOR回圈的每次迭代中導致在后臺進行大量檔案系統訪問,如果偶然發現檔案set.exe, set.bat,set.cmd等cmd.exe在某處,由于運行可執行檔案或呼叫批處理檔案而不是(重新)定義環境變數,批處理檔案不再按預期作業。
我寫的以下答案也可能會有所幫助:
- 如何逐行讀取和列印文本檔案的內容?
它詳細解釋了如何處理文本檔案的所有行。 - 如何通過參考另一個批處理檔案將環境變數作為引數傳遞?
它詳細解釋了命令SETLOCAL和ENDLOCAL的作用。 - 如何將變數中可能包含特殊字符(例如 % 或 !)的命令傳遞給 for /f 回圈?
這是一個批處理檔案示例,旨在在任何 Windows 計算機上處??理具有任何有效檔案名的視頻檔案,非常高效、安全和可靠,并附有完整說明。
uj5u.com熱心網友回復:
它的delayedexpansion模式似乎引發了這個問題。
@ECHO OFF
setlocal enabledelayedexpansion
echo This is an example^^^! > "textfile.txt"
echo This is a second example^^^! >> "textfile.txt"
echo And this line have an ^^^! exclamation mark in the middle >> "textfile.txt"
TYPE "textfile.txt"
SETLOCAL disabledelayedexpansion
for /F "usebackq tokens=* delims=" %%a in (textfile.txt) do (
set "Record=%%a"
CALL set "Output2=%%Output2%%%%record%% - "
CALL set "Output=%%Output%%%%a - "
SET out
)
)
endlocal&SET "output=%output%"
echo %Output%
echo !Output!
SET out
我毫不懷疑,在延遲擴展關閉的情況下,%. 只是特殊字符,我想。
請注意,使用endlocal&SET "output=%output%",是在模式下set執行的。delayedexpansion
uj5u.com熱心網友回復:
座位。我終于讓它作業了。它通過使用第二個文本檔案的解決方法來作業。不漂亮,不高性能,但它可以作業并且足以滿足我的目的。@Magoo,感謝您的帖子。
這是我的解決方案:
@echo off
setlocal enableextensions enabledelayedexpansion
echo This is an example^^!> "textfile.txt"
echo This is a second example^^!>> "textfile.txt"
echo And this line have an ^^! exclamation mark in the middle>> "textfile.txt"
echo.
echo Content of the textfile:
type "textfile.txt"
set output=
del "textfile2.txt" 1> nul 2>&1
setlocal disabledelayedexpansion
for /f "usebackq tokens=* delims=" %%a IN ("textfile.txt") do (
rem Write each line without a newline character into a new text file
echo|set /p "dummy=%%a, ">>"textfile2.txt"
)
endlocal
rem Loading the content of the new text file into the variable
set /p output=<"textfile2.txt"
del "textfile2.txt" 1> nul 2>&1
echo.
echo --------------------------------------------
echo Content of the variable:
set out
endlocal
輸出如下所示:
Content of the textfile:
This is an example!
This is a second example!
And this line have an ! exclamation mark in the middle
--------------------------------------------
Content of the variable:
output=This is an example!, This is a second example!, And this line have an ! exclamation mark in the middle,
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/470180.html
上一篇:G016-OS-LIN-CENT-01 CentOS 7.8.2003 安裝
下一篇:使用帶點的批處理檔案夾重命名
