当字符串中有括号时,如何用子字符串替换字符串 [英] How to replace a string with a substring when there are parentheses in the string

查看:96
本文介绍了当字符串中有括号时,如何用子字符串替换字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近两天我一直在努力尝试,试图编写一个读取文件夹结构并去除清单基本路径的代码.

I have been scratching my head for the last two days trying to put together a code that reads a folder structure and the strips off the base path of the listing.

到目前为止,我是这样的:

What I have so far is this:

@ECHO OFF
CLS
SETLOCAL EnableExtensions EnableDelayedExpansion

SET "StartTime=%TIME: =0%"
SET "Folder=%~1"
IF "%Folder:~-1%"=="\" SET "Folder=%Folder:~0,-1%"
FOR %%G IN ("%Folder%") DO SET "Archive=%%~nxG"
ECHO Processing %Folder%...
ECHO.
PUSHD "%Folder%"
FOR /F "DELIMS=" %%G IN ('DIR /A:-D /B /O:N /S') DO (
   SET "FullPath=%%G"
   ECHO !FullPath:%Folder%\=! >> "%Archive%.$$$"
)
pause
endlocal
goto :eof

只要目录没有(或)(例如C:\ Program Files(x86)\ AMD),此方法就可以正常工作,然后向我抛出错误消息并暂停.

This works fine as long the directory does not have ( or ) (e.g. C:\Program Files (x86)\AMD), then throws me an error message and halts.

找不到任何解决方案来绕过此限制.任何输入,不胜感激.谢谢!

Cannot find any solution to bypass this limitation. Any input is greatly appreciated. Thanks!

推荐答案

简单的解决方案是在 SET"FullPath = %% G" 下方插入以下命令行:

The simple solution is to insert the following command line below SET "FullPath=%%G":

SET "RelativePath=!FullPath:%Folder%\=!"

在双引号参数字符串内的右括号被解释为文字字符,而不是在命令块内发现的命令块结尾.

A closing parenthesis inside a double quoted argument string is interpreted as literal character and not as end of a command block on being found inside a command block.

然后将下一行更改为:

IF DEFINED RelativePath ECHO !RelativePath!>>"%Archive%.$$$"

此行将相对路径写入文件中,没有尾随空格,这是因为再也没有空间留给重定向操作符>> 了,该操作符也将由 ECHO 输出>.

This line writes the relative path into the file without a trailing space as there is no space anymore left to redirection operator >> which would be output also by ECHO.

因此批处理文件将是:

@ECHO OFF
CLS
SETLOCAL EnableExtensions EnableDelayedExpansion
IF "%~1" == "" GOTO :EOF

SET "Folder=%~1"
IF "%Folder:~-1%" == "\" SET "Folder=%Folder:~0,-1%"
FOR %%G IN ("%Folder%") DO SET "Archive=%%~nxG"
DEL "%Archive%.$$$" 2>NUL
ECHO Processing %Folder%...
ECHO/
FOR /F "DELIMS=" %%G IN ('DIR "%Folder%" /A:-D /B /O:N /S') DO (
   SET "FullPath=%%G"
   SET "RelativePath=!FullPath:%Folder%\=!"
   IF DEFINED RelativePath ECHO !RelativePath!>>"%Archive%.$$$"
)
ENDLOCAL
PAUSE

但是此解决方案仍然存在一些问题.

But there are several problems remaining with this solution.

  1. 如果分配给环境变量 Folder 的文件夹路径包含等号,则最后一个 FOR 循环内的字符串替换将无法正常工作.
  2. 分配给具有一个或多个感叹号的环境变量 Folder 的文件夹路径由于启用了延迟扩展而无法正确处理.
  3. DIR 在后台以一个或多个感叹号开始的单独命令过程中输出的标准文件名,由于启用了延迟扩展,因此无法正确处理.
  4. 使用驱动器的根文件夹路径(例如 D:\ 或仅使用 \ 引用当前驱动器的根目录)调用该批处理文件时,它无法按预期方式工作
  5. 批处理文件在使用相对路径调用时无法正常工作.
  6. ""调用时,会出现语法错误消息,退出批处理文件处理,因为这会导致语法错误的命令行 IF"".=="批处理文件执行过程中,转到:EOF .
  7. 在某些情况下,批处理文件未检测到传递到批处理文件的无效文件夹路径,例如 C:\ Temp \ * C:\ Temp:导致行为异常.
  1. If the folder path assigned to environment variable Folder contains an equal sign, the string substitution inside last FOR loop does not work as expected.
  2. A folder path assigned to environment variable Folder with one or more exclamation marks is not correct processed because of enabled delayed expansion.
  3. A full qualified file name output by DIR in separate command process started in background with one or more exclamation marks is not correct processed because of enabled delayed expansion.
  4. The batch file does not work as expected on being called with a root folder path of a drive like D:\ or just \ to reference the root of current drive.
  5. The batch file does not work as expected on being called with a relative path.
  6. Batch file processing is exited with a syntax error message on being called with """ as this results in the syntactically incorrect command line IF """ == "" GOTO :EOF during batch file execution.
  7. An invalid folder path like C:\Temp\* or C:\Temp: passed to the batch file is in some cases not detected by the batch file and results in not expected behavior.

请参阅Microsoft文档页面命名文件,路径,以及命名空间以及有关相对路径的详细信息.

See the Microsoft documentation page Naming Files, Paths, and Namespaces with details about relative paths.

下面注释的批处理文件甚至适用于那些不寻常的用例.

The commented batch file below works for even those unusual use cases.

@echo off
cls
setlocal EnableExtensions DisableDelayedExpansion

rem Do nothing if batch file called without a folder path
rem or with just one or more double quotes.
set "Folder=%~1"
if defined Folder set "Folder=%Folder:"=%"
if not defined Folder (
    echo Error: %~nx0 must be called with a folder path.
    goto EndBatch
)

rem Make sure the folder path contains backslashes and not forward slashes
rem and does not contain wildcard characters or redirection operators or a
rem horizontal tab character after removing all double quotes.
set "Folder=%Folder:/=\%"
for /F "delims=*?|<>    " %%I in ("%Folder%") do if not "%Folder%" == "%%I" (
    echo Error: %~nx0 must be called with a valid folder path.
    echo        "%~1" is not a valid folder path.
    goto EndBatch
)

rem Get full folder path in case of the folder was specified with a relative
rem path. If the folder path references the root of a drive like on using
rem "C:\" or just "\", redefine the folder path with full path for root of
rem the (current) drive. Determine also the name for the archive file to
rem create by this batch file in the current directory depending on name of
rem the folder to process respectively the drive in case of a root folder.
for %%I in ("%Folder%") do (
    set "Folder=%%~fI"
    set "ArchiveFile=%%~nxI.$$$"
)
if not "%Folder:~-1%" == "\" (
    set "Folder=%Folder%\"
) else (
    if "%Folder:~1,3%" == ":\" (
        set "ArchiveFile=Drive%Folder:~0,1%.$$$"
    ) else (
        for %%I in ("%Folder%.") do set "ArchiveFile=%%~nxI.$$$"
    )
)

rem Verify the existence of the folder. The code above processed also
rem folder paths of folders not existing at all and also invalid folder
rem paths containing for example a colon not (only) after drive letter.
if not exist "%Folder%" (
    echo Error: Folder "%Folder%" does not exist.
    goto EndBatch
)

rem Determine the number of folders in folder path.
set "FolderCount=0"
set "FolderRemain=%Folder%"
:CountFolders
set /A FolderCount+=1
for /F "tokens=1* delims=\" %%I in ("%FolderRemain%") do if not "%%J" == "" set "FolderRemain=%%J" & goto CountFolders

rem Write all files with path relative to base folder into the archive file.
echo Processing "%Folder%" ...
(for /F "tokens=%FolderCount%* delims=\" %%I in ('dir "%Folder%" /A:-D /B /O:N /S 2^>nul') do echo %%J)>"%ArchiveFile%"

rem Delete the archive file on being an empty file because of no file found.
for %%I in ("%ArchiveFile%") do if %%~zI == 0 (
    del "%ArchiveFile%"
    echo/
    echo Info: There are no files in folder: "%Folder%"
)

:EndBatch
endlocal
echo/
pause

注意:批处理文件中的定界符 *?|<> 后应该有一个水平制表符.

ATTENTION: There should be a horizontal tab character after the delimiters *?|<> in the batch file.

要了解所使用的命令及其工作方式,请打开命令提示符窗口,然后在此处执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call/? ...了解%〜nx0 (不带路径的批处理文件的名称)和%〜1 (引数1(不带双引号)
  • cls/?
  • del/?
  • dir/?
  • echo/?
  • endlocal/?
  • 用于/?
  • 转到/?
  • 如果/?
  • 暂停/?
  • rem/?
  • 设置/?
  • setlocal/?
  • call /? ... for an explanation of %~nx0 (name of batch file without path) and %~1 (argument 1 without surrounding double quotes)
  • cls /?
  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
  • rem /?
  • set /?
  • setlocal /?

另请参阅:

这是增强的批处理文件,它再次以更紧凑的形式出现,而没有注释:

Here is the enhanced batch file once again in a more compact form without comments:

@echo off & cls & setlocal EnableExtensions DisableDelayedExpansion

set "Folder=%~1"
if defined Folder set "Folder=%Folder:"=%"
if not defined Folder echo Error: %~nx0 must be called with a folder path.& goto EndBatch

set "Folder=%Folder:/=\%"
for /F "delims=*?|<>    " %%I in ("%Folder%") do if not "%Folder%" == "%%I" (
    echo Error: %~nx0 must be called with a valid folder path.
    echo        "%~1" is not a valid folder path.
    goto EndBatch
)

for %%I in ("%Folder%") do set "Folder=%%~fI" & set "ArchiveFile=%%~nxI.$$$"
if not "%Folder:~-1%" == "\" (set "Folder=%Folder%\") else if "%Folder:~1,3%" == ":\" (set "ArchiveFile=Drive%Folder:~0,1%.$$$") else for %%I in ("%Folder%.") do set "ArchiveFile=%%~nxI.$$$"
if not exist "%Folder%" echo Error: Folder "%Folder%" does not exist.& goto EndBatch

set "FolderCount=0"
set "FolderRemain=%Folder%"
:CountFolders
set /A FolderCount+=1
for /F "tokens=1* delims=\" %%I in ("%FolderRemain%") do if not "%%J" == "" set "FolderRemain=%%J" & goto CountFolders

echo Processing "%Folder%" ...
(for /F "tokens=%FolderCount%* delims=\" %%I in ('dir "%Folder%" /A:-D /B /O:N /S 2^>nul') do echo %%J)>"%ArchiveFile%"
for %%I in ("%ArchiveFile%") do if %%~zI == 0 del "%ArchiveFile%"& echo/& echo Info: There are no files in folder: "%Folder%"

:EndBatch
endlocal & echo/& pause

这篇关于当字符串中有括号时,如何用子字符串替换字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆