拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 在最后一个空格之后将变量缩减为全部

在最后一个空格之后将变量缩减为全部

白鹭 - 2022-02-16 2095 0 0

我有以下内容,它将档案夹名称 (FOLDER) 缩减为仅在第一个空格 (tmpFOLDER) 之前的所有文本。

@echo off
setlocal EnableExtensions DisableDelayedExpansion
pushd "%~dp0" || exit /B
for %%I in (..) do set "FOLDER=%%~nxI"
for /f "tokens=1 delims= " %%a in ("%FOLDER%") do set tmpFOLDER=%%a

ECHO %FOLDER%
ECHO %tmpFOLDER%

popd
endlocal

主要要求:

有没有办法反过来做到这一点?

档案夹名称 (%FOLDER%):Smith - John

当前示例 (%tmpFOLDER%):Smith

所需示例 (%tmpFOLDER%):John

中学:

有没有办法对档案执行此操作,而不考虑任何档案型别(即 .txt)?

文件名 (%FILE%): "Smith - John.txt"

当前示例 (%tmpFILE%):Smith

所需示例 (%tmpFILE%):John

uj5u.com热心网友回复:

for /F可以不从字符串中提取的结束计数令牌。但是,您可以使用标准for回圈遍历档案或目录名称的单词:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Retrieve base name of grand-parent directory of this script:
for /D %%I in ("%~dp0..") do set "FOLDER=%%~nI"
echo Old name: "%FOLDER%"

set "PREV=" & set "COLL="
rem /* Unnecessary loop iterating once and returning the whole directory name;
rem    it is just here to demonstrate how to handle also more than one names: */
for /F "delims= eol=|" %%L in ("%FOLDER%") do (
    rem // Store current name strng and reset some interim variables:
    set "NAME=%%L" & set "PREV=" & set "COLL= "
    rem // Toggle delayed expansion to avoid issues with `!` and `^`:
    setlocal EnableDelayedExpansion
    rem // Ensure to have each space-separated word quoted, then loop through them:
    for %%K in ("!NAME: =" "!") do (
        rem /* Build new buffer by concatenating word from previous loop iteration,
        rem    then transfer it over `endlocal` barrier (localised environment): */
        for %%J in ("!COLL! !PREV!") do (
            rem // Store current word in an unquoted manner:
            endlocal & set "ITEM=%%~K"
            rem // Store current buffer, store current word for next iteration:
            set "COLL=%%~J" & set "PREV=%%~K"
            setlocal EnableDelayedExpansion
        )
    )
    endlocal
)
rem // Retrieve final result:
set "RESULT=%COLL:~3%"
echo New name: "%RESULT%"
echo Last word: "%PREV%"

endlocal
exit /B

此方法回传洗掉了最后一个单词的名称以及名称的最后一个单词。


另一种解决方案是有时所谓的代码注入技术,它需要延迟变量扩展并且很难理解:

setlocal EnableDelayedExpansion
echo Old name: "%FOLDER%"
set "RESULT=%FOLDER: =" & set "RESULT=!RESULT!!ITEM!" & set "ITEM= %"
echo New name: "%RESULT%"
echo Last word: "%ITEM:* =%"
endlocal

请注意,当输入字符串包含!, ^or时,这将失败"(但后者无论如何都不会出现在档案或目录名称中)。


另一种方法是替换空格\,然后(错误)使用~-modifiers,这是因为纯档案或目录名称不能单独包含\

echo Old name: "%FOLDER%"
rem // Precede `\` to make pseudo-path relative to root, then replace each ` ` by `\`:
for %%I in ("\%FOLDER: =\%") do (
    rem // Let `for` meta-variable expansion do the job:
    set "RESULT=%%~pI"
    set "LAST=%%~nxI"
)
rem // Remove leading and trailing `\`; then revert replacement of ` ` by `\`:
set "RESULT=%RESULT:~1,-1%"
echo New name: "%RESULT:\= %"
echo Last word: "%LAST%"

这种方法甚至不需要延迟扩展

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *