[英]Batch file to download a file with name that starts with a given string from FTP
[英]Batch file if string starts with
我試圖弄清楚字符串是否以 substring 開頭:
rem GetInput
if "%result%"=="cd *" goto Cd
:Cd
if "%result%"=="cd meow" Echo Going to directory 'meow'...
不幸的是,這並沒有在應該的時候循環回到:Cd。 如何檢測字符串是否以cd
開頭?
如果我理解正確,那么您正在嘗試確定%result%
值是否以 'cd' 開頭,並且您沒有成功使用*
作為通配符來確定這一點。
有幾種不同的方法來處理這個問題。 這是一種方法:您可以檢查前兩個字符是否等於 'cd':
if /i "%result:~0,2%"=="cd" goto Cd
set /?
有更多關於這個。
標題比用例更廣泛,這使得通用 startsWith 對於特定問題有點矯枉過正——正如 Wes 所說,對於這個特定問題,您可以只檢查前兩個字符並檢查cd
。
但請記住這一點,讓我們回答標題中更籠統的問題。
DOSTips.com的 startsWith 解決方案看起來很不錯。
:StartsWith text string -- Tests if a text starts with a given string
:: -- [IN] text - text to be searched
:: -- [IN] string - string to be tested for
:$created 20080320 :$changed 20080320 :$categories StringOperation,Condition
:$source https://www.dostips.com
SETLOCAL
set "txt=%~1"
set "str=%~2"
if defined str call set "s=%str%%%txt:*%str%=%%"
if /i "%txt%" NEQ "%s%" set=2>NUL
EXIT /b
這似乎可行,但它並沒有真正返回一個值,而且它的變量名非常 1990 年代。
我破解了這個:
:startsWith
set "haystack1=%~1"
set "needle2=%~2"
if defined needle2 call set "s=%needle2%%%haystack1:*%needle2%=%%"
if /i "%haystack1%" NEQ "%s%" (
exit /b 0
)
EXIT /b 1
這將在%errorlevel%
中返回1
表示是,does-start-with, 0
表示否,does-NOT-start-with。 您可能會爭辯說 does-start-with 應該為“無錯誤”返回0
。 如果你有強烈的感覺,顯然歡迎你在你的實現中交換它們。 我要說“零傳統上是虛假的,所以它代表一個錯誤的返回值”。 YMMV, .
這是一個完整的例子來測試......
@ECHO OFF
call :startsWith slappy slap
echo %errorlevel%
echo.
call :startsWith slap slappy
echo %errorlevel%
echo.
call :startsWith slappy spam
echo %errorlevel%
echo.
call :startsWith slappy lap
echo %errorlevel%
echo.
call :startsWith spam
echo %errorlevel%
echo.
exit /b 0
:startsWith
set "haystack1=%~1"
set "needle2=%~2"
set "s="
REM I think this is okay b/c if %2 was defined, %1 kinda has to be too.
if defined needle2 call set "s=%needle2%%%haystack1:*%needle2%=%%"
echo needle: %needle2%
echo haystack: %haystack1%
echo s: %s%
if /i "%haystack1%" NEQ "%s%" (
exit /b 0
)
EXIT /b 1
needle: slap
haystack: slappy
s: slappy
1
needle: slappy
haystack: slap
s: slappyslap
0
needle: spam
haystack: slappy
s: spamslappy
0
needle: lap
haystack: slappy
s: lappy
0
needle:
haystack: spam
s:
0
這是一個巧妙的技巧。 它基本上...
needle
開頭的新字符串needle
出現在haystack
中的任何位置, haystick
在needle
出現后出現的部分添加到新字符串中。 否則將所有haystack
添加到您的新字符串中。haystack
,你就贏了。 否則你輸了。 因此,如果 needle 是slap
並且 haystack 是slappy
,則%s%
將是slap
plus [ slap
之后的slappy
內容是...] py
。 這給了我們slappy
,它與haystack
中的內容相匹配,我們贏了。
如果 needle 是spam
而 haystack 是slappy
, %s%
將從spam
開始,然后,由於spam
不在slappy
中,我們添加所有haystack
。 這給我們留下了spamslappy
,我們輸了。 ( spamslappy
?這就是喜劇。)
一個巧妙的失敗是當你尋找一些在大海撈針中但不在haystack
開始處的東西時,就像在我們的lap
示例中一樣。 也就是說,如果 needle 是lap
而 haystack 是slappy
, %s%
將從lap
開始,然后,從lap
in slappy
結束的所有內容也給出py
,我們有lap
加py
或lappy
,這不是slappy
,並且我們又輸了,但以一種新的、很酷的方式。
參數引用刪除。 命令行參數(例如
"%~1"
)前的波浪號表示從參數中刪除周圍的引號。 這樣,如果%1
的值為"Hi"
,則%~1
將擴展為僅Hi
。
call set "s=%str%%%txt:*%str%=%%"
有點復雜。
首先了解冒號 ( :
表示我們正在使用“ 字符串替換功能”:
此代碼取自同一頁面,用%str
中的has
替換了needs
:
set str=%str:needs=has%
echo %str%
那么我們需要知道...
“StrToFind” [在
:
之后] 可以以星號開頭,在這種情況下它將替換“StrToFind”左側的所有字符。
...::Delete the character string 'ab' and everything before it SET _test=12345abcabc SET _result=%_test:*ab=% ECHO %_result% =cabc
然后看到這個答案:
那里的
call
會導致另一層變量擴展,因此有必要 [轉義] 原始的%
符號,但最終一切都會解決。
現在call set "s=%str%%%txt:*%str%=%%"
應該有意義了。
關於這個問題的另一個答案表明 DOSTips 中的 startsWith 方法比這里的其他答案要少一些 finnicky,因為......
您可以使用,。 但您必須設置 ENABLEDELAYEDEXPANSION 開關。
我們正在避免這種情況。
而且,最后...
如果你對所有這些神秘規則的瘋狂感到震驚,你應該學習 PowerShell,太棒了!
哈,好的。 但我們仍然可以在不離開批次的情況下完成它。 享受!
這是一個相對強大且通用的startsWith
子例程(有兩個示例)。如果字符串以另一個字符串開頭,則將 errorlevel 設置為 1,如果不是,則設置為 0。
@echo off
set string1=abc123123
set checker1=abc
call :startsWith %string1% %checker1%
if %errorlevel% equ 1 (
echo %string1% starts with %checker1%
) else (
echo %string1% does NOT start with %checker1%
)
set string2=xyz123123 abc
call :startsWith %string2% %checker2%
if %errorlevel% equ 1 (
echo %string2% starts with %checker2%
) else (
echo %string2% does NOT start with %checker2%
)
exit /b 0
::::::::::::::::::::::::::::::::::::::::
:::----- subroutine starts here ----::::
:startsWith [%1 - string to be checked;%2 - string for checking ]
@echo off
rem :: sets errorlevel to 1 if %1 starts with %2 else sets errorlevel to 0
setlocal EnableDelayedExpansion
set "string=%~1"
set "checker=%~2"
rem set "var=!string:%~2=&echo.!"
set LF=^
rem ** Two empty lines are required
rem echo off
for %%L in ("!LF!") DO (
for /f "delims=" %%R in ("!checker!") do (
rem set "var=!string:%%~R%%~R=%%~L!"
set "var=!string:%%~R=#%%L!"
)
)
for /f "delims=" %%P in (""!var!"") DO (
if "%%~P" EQU "#" (
endlocal & exit /b 1
) else (
endlocal & exit /b 0
)
)
::::::::::::::::::::::::::::::::::::::::::::::::::
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.