如何从字符串中删除第一次出现的子字符串?

问题描述 投票:0回答:3

我正在处理并且只能使用批处理文件。没有 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\
的位置,然后继续提取之前的字符串和之后的字符串,最后连接。没有任何成功。

更新1:

有了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...

	
string batch-file find
3个回答
1
投票
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
的字符串中的感叹号被解释为延迟扩展变量引用的开始/结束,导致在进一步处理之前对该字符串进行适当修改,从而导致错误的文件名称/目标字符串处理。
    


1
投票

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
。如果没有子例程正在进行,则到达文件结尾将终止子例程或主例程。
    


1
投票

@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\
字符串的位置

© www.soinside.com 2019 - 2024. All rights reserved.