我正在处理并且只能使用批处理文件。没有 PowerShell。
我想删除字符串中第一个出现的子字符串。
@echo off
@setlocal enableextensions enabledelayedexpansion
set "str=C:\help\te\Windows\Example\001 Example\te\005 Example"
echo -----------Original string---------------------------
echo !str!
echo ----------This removes EVERY \te\----------------------------
echo !str:\te\=\!
echo -----------This gets everything after first \te\---------------------------
set "strAfter=!str:*\te\=\!"
echo !strAfter!
echo ----------This gets everything before first \te\----------------------------
echo how?
echo ---------simply get rid of FIRST \te\-----------------------------
echo how?
echo -----------------I could work with the position of the first \te\-------------------------------
echo how?
PAUSE
我已经玩过上面的内容了。我玩过
for
循环、
find
、findstr
。我还想过获取第一个
\te\
有了Magoo的技巧,我就能让它发挥作用。谢谢。 (仍在阅读双引号,%%
,
&&
和!!
。)echo:
echo ------ This gets everything before first \te\--------
rem Replace "everything after \te\" with nothing, then remove \te again
set "strBefore=!str:%strAfter%=!"
set "strBefore=!strBefore:\te=!"
echo !strBefore!
echo:
echo ------ First method--------
set "finalstr=!strBefore!!strAfter!"
echo !finalStr!
如果我需要的话,我仍然很想获得一个职位。
echo:
echo ----(Method2)-- I could work with the position of the first \te\--------
echo ------ if I could get the 7 automatically
set /a ind=7
set before=!str:~0,%ind%!
set after=!str:*\te\=\!
set finalstr=!before!!after!
echo !finalstr!
很好奇,真的没有简单的 1 或 2 行搜索来查找FIRST
出现吗?
更新2:虽然上面的小测试脚本有效,但一旦我将其带回实际脚本中,它就会崩溃。这是官方脚本。
@ECHO off
@setlocal enabledelayedexpansion
REM find filenames that are links
For /R %%G in (*.lnk) do (
echo:
echo --------------------------------
set originalLink=%%G
echo For this link : !originalLink!
REM find the Target/cible
for /F "tokens=1 delims=" %%a in ('shortcutJS.bat -examine "%%G" ^| find /i "Target:"') do (
set "targetVar=%%a"
)
REM remove word Target: from front (use double quotes in case of spaces)
set "targetVar=!targetVar:Target:=!"
echo Target file is : !targetVar!
rem TODO count how many \te\ to put an if to skip if useless
REM remove or replace the FIRST folder named \te\ from path
set "strAfter=!targetVar:*\te\=\!"
echo strAfter first \te\: !strAfter!
REM Replace "everything after \te\" with nothing, then remove \te again
set "strBefore=!targetVar:%strAfter%=!"
echo strBefore is: !strBefore!
set "strBefore=!strBefore:\te=!"
echo strBefore: !strBefore!
set "targetNew=!strBefore!!strAfter!"
echo targetNew !targetNew!
REM this would remove every \te\... not good if more than one. trying to change with what's above.
set targetNew=!targetVar:\te\=\!
echo:
echo New target : !targetNew!
REM actually push the new Target to the file...
REM editShortcut.vbs "!originalLink!" "!targetNew!"
PAUSE
)
strAfter
有效,但
strBefore
无效。这是一个输出:--------------------------------
For this link : C:\Users\carol\Desktop\tests raccourcis names serveur\renameLinks2\horloge velo.jpg.lnk
Target file is : C:\Users\carol\Desktop\tests raccourcis names serveur\te\horloge velo.jpg
strAfter first \te\: \horloge velo.jpg
strBefore is: targetVar:=
strBefore: targetVar:=
targetNew targetVar:=\horloge velo.jpg
New target : C:\Users\carol\Desktop\tests raccourcis names serveur\horloge velo.jpg
Appuyez sur une touche pour continuer...
te
从字符串中删除。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "str=C:\help\te\Windows\Example\001 Example\te\005 Example"
rem Replace all \te\ by | in the string which no file/folder name
rem can have ever at all. There could be used also ? or other
rem characters not allowed in a file/folder name except *.
set "str=%str:\te\=|%"
rem Split up the file/folder name string never beginning with
rem a semicolon into two parts: the string left to first | and
rem the remaining part with zero or more vertical bars. Then
rem concatenate the two strings with a backslash between theme.
for /F "tokens=1* delims=|" %%I in ("%str%") do set "str=%%I\%%J"
rem Replace all still existing | back to \te\ to get the resulting string.
set "str=%str:|=\te\%"
set str
pause
endlocal
该批处理文件的输出是:
str=C:\help\Windows\Example\001 Example\te\005 Example
此代码可以在重写的主批处理文件中使用。
@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem Find file names of shortcut files.
for /R %%G in (*.lnk) do (
echo(
echo --------------------------------
echo For this shortcut: %%G
rem Find the target/cible.
for /F "tokens=1* delims=: " %%I in ('^""%~dp0shortcutJS.bat" -examine "%%G" ^| %SystemRoot%\System32\find.exe /I "Target:"^"') do set "targetNew=%%J"
echo Target file is: !targetNew!
rem Remove the first folder with name te from new target string.
set "targetNew=!targetNew:\te\=|!
for /F "tokens=1* delims=|" %%I in ("!targetNew!") do set "targetNew=%%I\%%J"
set "targetNew=!targetNew:|=\te\!"
echo The new target is: !targetNew!
rem %SystemRoot%\System32\cscript.exe //B //NoLogo "%~dp0editShortcut.vbs" "%%G" "!targetNew!"
pause
)
endlocal
主批处理文件中有一些与问题无关的修改。一些主题由这个答案
shortcutJS.bat
(很可能是 BAT/JS 混合体或 BAT/VBS 混合体,文件名有误)和 VBScript 文件
editShortcut.vbs
很可能与主批处理文件位于同一目录中并被引用因此,它们具有完全限定的文件名。通过此修改,批处理文件执行的当前工作目录可以是通过第一个 FOR循环递归搜索文件扩展名
.lnk
的快捷方式文件的任何目录。
注意:如果任何快捷方式文件名包含一个或多个!
,或者由于永久启用延迟变量扩展而导致
shortcutJS.bat
的任何目标输出包含一个或多个感叹号,则主批处理文件的代码不起作用。分配给循环变量 G
、I
和 J
的字符串中的感叹号被解释为延迟扩展变量引用的开始/结束,导致在进一步处理之前对该字符串进行适当修改,从而导致错误的文件名称/目标字符串处理。 rem use constant value in place of '%%G'
set "targetVar=Target:c:\Users\Carol\tests raccoursis names serveur\te\horlorge velo.jpg"
REM remove word Target: from front (use double quotes in case of spaces)
set "targetVar=!targetVar:Target:=!"
echo Target file is : !targetVar!
rem TODO count how many \te\ to put an if to skip if useless
REM remove or replace the FIRST folder named \te\ from path
set "strAfter=!targetVar:*\te\=!"
echo strAfter first \te\: !strAfter!
REM Replace "everything after \te\" with nothing, then remove \te\ again
CALL :removete
echo strBefore is: !strBefore!
rem set "strBefore=!strBefore:\te=!"
rem echo strBefore: !strBefore!
ECHO this is without the REPLACEment FOR \te\
set "targetNew=!strBefore!!strAfter!"
echo targetNew !targetNew!
ECHO this is with a REPLACEment FOR \te\
set "targetNew=!strBefore!\replacement directory\!strAfter!"
echo targetNew !targetNew!
最后
)
线之后,
GOTO :EOF
:removete
set "strBefore=!targetVar:\te\%strAfter%=!"
GOTO :eof
备注:
我更喜欢根据需要显式插入常量
\
,而不是在变量值中使用前导/尾随字符。恕我直言,它使处理更容易设计和维护。 YMMV.
在您的代码中,您使用了 set "strBefore=!targetVar:%strAfter%=!"
在该语句中,
%strAfter%
将被遇到
strAfter
语句时的 for
值替换 - 在执行之前,当然不是循环中更改的值。 变量的行为不符合预期注意对内部子例程
removete
的调用。冒号是必需的(将例程标记为内部)。
:EOF
(不区分大小写,但需要冒号)表示
End Of File
。如果没有子例程正在进行,则到达文件结尾将终止子例程或主例程。@echo off
setlocal EnableDelayedExpansion
set "str=C:\help\te\Windows\Example\001 Example\te\005 Example"
echo Old: "%str%"
set "repl=\" & set "new=%str:\te\=!repl!" & set "repl=\te\" & set "new=!new!%"
echo New: "%new%"
输出:
Old: "C:\help\te\Windows\Example\001 Example\te\005 Example"
New: "C:\help\Windows\Example\001 Example\te\005 Example"
有关所用方法的进一步描述,请参阅这个答案
获取第一个(或全部)
\te\
字符串的位置