배치 파일에서 어디에서 길이를 어떻게 얻습니까?
배치 파일에서 용이 한 길이를 얻을 수 있습니다. 예 :
SET MY_STRING=abcdefg
SET /A MY_STRING_LEN=???
-length를 문자열 MY_STRING
어떻게 찾을 수 있습니까?
이스케이프 길이 함수가 다음과 같이 이스케이프 문자를 포함하여 많은 것에서 가능한 모든 문자를 처리하는 경우 포인트가 제공 !%^^()^!
됩니다.
이미있는 길이에 대한 내장 함수가 내부 다음과 같이 고유 한 함수를 사용할 수 있습니다.
@echo off
setlocal
REM *** Some tests, to check the functionality ***
REM *** An emptyStr has the length 0
set "emptyString="
call :strlen result emptyString
echo %result%
REM *** This string has the length 14
set "myString=abcdef!%%^^()^!"
call :strlen result myString
echo %result%
REM *** This string has the maximum length of 8191
setlocal EnableDelayedExpansion
set "long=."
FOR /L %%n in (1 1 13) DO set "long=!long:~-4000!!long:~-4000!"
(set^ longString=!long!!long:~-191!)
call :strlen result longString
echo %result%
goto :eof
REM ********* function *****************************
:strlen <resultVar> <stringVar>
(
setlocal EnableDelayedExpansion
(set^ tmp=!%~2!)
if defined tmp (
set "len=1"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!tmp:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "tmp=!tmp:~%%P!"
)
)
) ELSE (
set len=0
)
)
(
endlocal
set "%~1=%len%"
exit /b
)
이 함수는 strlen 루프가 필요한 단순한 strlen 함수 대신 항상 13 개의 루프가 필요합니다.
모든 문자를 처리합니다.
(set^ tmp=!%~2!)
매우 긴 발송을 처리해야하는 이상한 표현 이 필요합니다. 텍스트 복사 할 수 없습니다.
이전 파일에 쓴 다음 파일의 길이를 가져 오기 두 줄로 전체 배치 파일로 수행 할 수 있습니다. 끝에 추가 된 자동 CR + LF를 설명하기 위해 2 바이트를 빼면됩니다.
가정 해 보겠습니다 strvar
.
ECHO %strvar%> tempfile.txt
FOR %%? IN (tempfile.txt) DO ( SET /A strlength=%%~z? - 2 )
이미의 길이는 이제라는 변수에 strlength
있습니다.
좀 더 자세히 설명하면 다음과 가변합니다.
FOR %%? IN (filename) DO ( ...
: 파일에 대한 정보를 얻습니다.SET /A [variable]=[expression]
: 수식을 숫자로 평가%%~z?
: 파일의 길이를 구하는 특수
전체 명령을 한 줄로 매시 비용 :
ECHO %strvar%>x&FOR %%? IN (x) DO SET /A strlength=%%~z? - 2&del x
나는 jeb의 허용되는 솔루션 을 선호합니다 . (실제로 DosTips에는 몇 가지 추가 비용을 추가 할 수 있습니다.
그러나 새롭고 효율적인 알고리즘을 생각해내는 것이 재미 있습니다. 다음은 FINDSTR / O 옵션을 사용하는 새로운 알고리즘입니다.
@echo off
setlocal
set "test=Hello world!"
:: Echo the length of TEST
call :strLen test
:: Store the length of TEST in LEN
call :strLen test len
echo len=%len%
exit /b
:strLen strVar [rtnVar]
setlocal disableDelayedExpansion
set len=0
if defined %~1 for /f "delims=:" %%N in (
'"(cmd /v:on /c echo(!%~1!&echo()|findstr /o ^^"'
) do set /a "len=%%N-3"
endlocal & if "%~2" neq "" (set %~2=%len%) else echo %len%
exit /b
파서가 명령을 저글링하고 CMD / V / C가 명령을 실행하기 전에 공백을 추가하기 때문에 코드는 3을 부담니다. 를 사용하여 예방할 수 있습니다 (echo(!%~1!^^^)
.
가능한 절대적으로 가장 빠른 성능을 원하는 사람들을 위해 jeb의 대답을 인수와 함께 배치 "매크로"로 사용할 수 있습니다 . 이것은 서브 루틴을 호출하는 내부적으로 느린 프로세스를 제거하는 DosTips에서 개발 된 고급 배치 기술입니다. 여기 에서 배치 매크로의 개념에 대한 더 많은 배경 정보를 얻을 수있는 링크는 더 원시적 인 덜 바람직한 구문을 사용합니다.
아래는 최적화 된 @strLen 매크로로, 매크로와 : subroutine 사용의 차이점과 성능 차이를 그래픽 예제입니다.
@echo off
setlocal disableDelayedExpansion
:: -------- Begin macro definitions ----------
set ^"LF=^
%= This creates a variable containing a single linefeed (0x0A) character =%
^"
:: Define %\n% to effectively issue a newline with line continuation
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
:: @strLen StrVar [RtnVar]
::
:: Computes the length of string in variable StrVar
:: and stores the result in variable RtnVar.
:: If RtnVar is is not specified, then prints the length to stdout.
::
set @strLen=for %%. in (1 2) do if %%.==2 (%\n%
for /f "tokens=1,2 delims=, " %%1 in ("!argv!") do ( endlocal%\n%
set "s=A!%%~1!"%\n%
set "len=0"%\n%
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (%\n%
if "!s:~%%P,1!" neq "" (%\n%
set /a "len+=%%P"%\n%
set "s=!s:~%%P!"%\n%
)%\n%
)%\n%
for %%V in (!len!) do endlocal^&if "%%~2" neq "" (set "%%~2=%%V") else echo %%V%\n%
)%\n%
) else setlocal enableDelayedExpansion^&setlocal^&set argv=,
:: -------- End macro definitions ----------
:: Print out definition of macro
set @strLen
:: Demonstrate usage
set "testString=this has a length of 23"
echo(
echo Testing %%@strLen%% testString
%@strLen% testString
echo(
echo Testing call :strLen testString
call :strLen testString
echo(
echo Testing %%@strLen%% testString rtn
set "rtn="
%@strLen% testString rtn
echo rtn=%rtn%
echo(
echo Testing call :strLen testString rtn
set "rtn="
call :strLen testString rtn
echo rtn=%rtn%
echo(
echo Measuring %%@strLen%% time:
set "t0=%time%"
for /l %%N in (1 1 1000) do %@strlen% testString testLength
set "t1=%time%"
call :printTime
echo(
echo Measuring CALL :strLen time:
set "t0=%time%"
for /l %%N in (1 1 1000) do call :strLen testString testLength
set "t1=%time%"
call :printTime
exit /b
:strlen StrVar [RtnVar]
::
:: Computes the length of string in variable StrVar
:: and stores the result in variable RtnVar.
:: If RtnVar is is not specified, then prints the length to stdout.
::
(
setlocal EnableDelayedExpansion
set "s=A!%~1!"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" neq "" (
set /a "len+=%%P"
set "s=!s:~%%P!"
)
)
)
(
endlocal
if "%~2" equ "" (echo %len%) else set "%~2=%len%"
exit /b
)
:printTime
setlocal
for /f "tokens=1-4 delims=:.," %%a in ("%t0: =0%") do set /a "t0=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100
for /f "tokens=1-4 delims=:.," %%a in ("%t1: =0%") do set /a "t1=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100
set /a tm=t1-t0
if %tm% lss 0 set /a tm+=24*60*60*100
echo %tm:~0,-2%.%tm:~-2% msec
exit /b
-샘플 출력-
@strLen=for %. in (1 2) do if %.==2 (
for /f "tokens=1,2 delims=, " %1 in ("!argv!") do ( endlocal
set "s=A!%~1!"
set "len=0"
for %P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%P,1!" neq "" (
set /a "len+=%P"
set "s=!s:~%P!"
)
)
for %V in (!len!) do endlocal&if "%~2" neq "" (set "%~2=%V") else echo %V
)
) else setlocal enableDelayedExpansion&setlocal&set argv=,
Testing %@strLen% testString
23
Testing call :strLen testString
23
Testing %@strLen% testString rtn
rtn=23
Testing call :strLen testString rtn
rtn=23
Measuring %@strLen% time:
1.93 msec
Measuring CALL :strLen time:
7.08 msec
처음 몇 줄은 표시 : strLen 함수를 보여주기위한 것입니다.
@echo off
set "strToMeasure=This is a string"
call :strLen strToMeasure strlen
echo.String is %strlen% characters long
exit /b
:strLen
setlocal enabledelayedexpansion
:strLen_Loop
if not "!%1:~%len%!"=="" set /A len+=1 & goto :strLen_Loop
(endlocal & set %2=%len%)
goto :eof
물론 이것은 jeb에서 제공하는 "13 loop"버전에서 그다지 처음으로 사용합니다. 그러나 이해하기가 더 복잡한 3GHz 컴퓨터는 몇 분의 1 초 안에 수천 번의 반복을 통과 할 수 있습니다.
예, 물론 vbscript (또는 powershell)를 사용하는 쉬운 방법이 있습니다.
WScript.Echo Len( WScript.Arguments(0) )
명령 strlen.vbs
줄에 저장
c:\test> cscript //nologo strlen.vbs "abcd"
for 루프를 사용하여 결과적으로 사용 (또는 스크립팅 작업에 vbscript 전적으로 사용)
배치를 사용하여 번거로운 해결 방법을 더 좋으며 vbscript는 각 Windows 배포 (및 나중에 powershell)에서 사용할 수 있기 때문에 사용할 수 없습니다.
방금 ULTIMATE 솔루션을 찾았습니다.
set "MYSTRING=abcdef!%%^^()^!"
(echo "%MYSTRING%" & echo.) | findstr /O . | more +1 | (set /P RESULT= & call exit /B %%RESULT%%)
set /A STRLENGTH=%ERRORLEVEL%-5
echo string "%MYSTRING%" length = %STRLENGTH%
출력은 다음과 가변합니다.
string "abcdef!%^^()^!" length = 14
이스케이프 문자를 처리하며 위의 대부분의 솔루션보다 훨씬 간단하며 루프, 매직 넘버, DelayedExpansion, 임시 파일 등을 포함하지 않습니다.
배치 펼쳐 외부에서 사용하는 경우 (명령을 콘솔에 수동으로 넣는 것을 의미 함) 키 %%RESULT%%
를 %RESULT%
.
필요한 경우 NOP 명령 %ERRORLEVEL%
을 FALSE
사용하여 변수를 접근 할 수 있습니다.echo. >nul
Windows Vista +를 사용하는 경우 다음 Powershell 방법을 시도하십시오.
For /F %%L in ('Powershell $Env:MY_STRING.Length') do (
Set MY_STRING_LEN=%%L
)
또는 대안으로 :
Powershell $Env:MY_STRING.Length > %Temp%\TmpFile.txt
Set /p MY_STRING_LEN = < %Temp%\TmpFile.txt
Del %Temp%\TmpFile.txt
나는 Windows 7 x64를 사용하고 있으며 이것은 나를 위해 일하고 있습니다.
jmh_gr 의 두 줄 접근 방식 을 좋아합니다.
()
리디렉션 전에 명령 부분을 둘러싼 경우 가 아니면 한 자리 숫자로 작동하지 않습니다 . 이후 1>
특별한 명령은 파일로 리디렉션됩니다.
이 예제는 한 자리 숫자를 처리해야 할 때 <
사용할 수 있는 기타 특수 문자는 처리하지 않습니다 .
(ECHO %strvar%)> tempfile.txt
단 몇 줄의 확장 길이를 계산하는 또 다른 배치 펼쳐집니다. 가장 빠르지는 않지만 꽤 작습니다. 서브 루틴 ": len"은 두 번째 매개 변수의 길이를 리턴합니다. 첫 번째 번째 매개 변수는 분석되는 문자열입니다. 참고-특수 문자는 이스케이프되어야합니다. 즉, 배치 파일의 많은이있는 경우입니다.
@echo off
setlocal
call :len "Sample text" a
echo The string has %a% characters.
endlocal
goto :eof
:len <string> <length_variable> - note: string must be quoted because it may have spaces
setlocal enabledelayedexpansion&set l=0&set str=%~1
:len_loop
set x=!str:~%l%,1!&if not defined x (endlocal&set "%~2=%l%"&goto :eof)
set /a l=%l%+1&goto :len_loop
@echo off & setlocal EnableDelayedExpansion
set Var=finding the length of strings
for /l %%A in (0,1,10000) do if not "%Var%"=="!Var:~0,%%A!" (set /a Length+=1) else (echo !Length! & pause & exit /b)
var =로 변경하여 사용자가 입력합니다. 나중에 참조 할 수 있도록 여기에 넣습니다.
@echo off
:: warning doesn't like * ( in mystring
setlocal enabledelayedexpansion
set mystring=this is my string to be counted forty one
call :getsize %mystring%
echo count=%count% of "%mystring%"
set mystring=this is my string to be counted
call :getsize %mystring%
echo count=%count% of "%mystring%"
set mystring=this is my string
call :getsize %mystring%
echo count=%count% of "%mystring%"
echo.
pause
goto :eof
:: Get length of mystring line ######### subroutine getsize ########
:getsize
set count=0
for /l %%n in (0,1,2000) do (
set chars=
set chars=!mystring:~%%n!
if defined chars set /a count+=1
)
goto :eof
:: ############## end of subroutine getsize ########################
나는 코드를 / 펼쳐 / 등을 작성하는 것을 많이 알고 말하면서 시작하고 싶습니다. 그러나 내가 생각해 낸 것 같은 해결책을 공유 할 생각했습니다. 여기에있는 대부분의 답변은 제 머릿속을 넘어서서 제가 쓴 내용이 지 궁금했습니다.
@echo off
set stringLength=0
call:stringEater "It counts most characters"
echo %stringLength%
echo.&pause&goto:eof
:stringEater
set var=%~1
:subString
set n=%var:~0,1%
if "%n%"=="" (
goto:eof
) else if "%n%"==" " (
set /a stringLength=%stringLength%+1
) else (
set /a stringLength=%stringLength%+1
)
set var=%var:~1,1000%
if "%var%"=="" (
goto:eof
) else (
goto subString
)
goto:eof
그것은 훨씬 더 간단합니다 !
순수한 배치 솔루션. 임시 파일이 없습니다. 긴 펼쳐지지 않습니다.
@echo off
setlocal enabledelayedexpansion
set String=abcde12345
for /L %%x in (1,1,1000) do ( if "!String:~%%x!"=="" set Lenght=%%x & goto Result )
:Result
echo Lenght: !Lenght!
1000
예상되는 최대 확장 길이입니다. 필요에 따라 변경하십시오.
@ECHO OFF
SET string=
SET /A stringLength=0
:CheckNextLetter
REM Subtract the first letter and count up until the string="".
IF "%string%" NEQ "" (
SET string=%string:~1%
SET /A stringLength=%stringLength%+1
GOTO :CheckNextLetter
) ELSE (
GOTO :TheEnd
)
:TheEnd
ECHO There is %stringLength% character^(s^) in the string.
PAUSE
이것은 나를 위해 작동합니다. 이것이 다른 사람에게 유용하기를 바랍니다. 길이가 필요 없습니다. 첫 번째 문자를 제거하고 제거하고 ""가 될 때까지 ""와 비교합니다.
참고 URL : https://stackoverflow.com/questions/5837418/how-do-you-get-the-string-length-in-a-batch-file
'ProgramingTip' 카테고리의 다른 글
Perl에서 YYYY-mm-dd HH : MM : SS로 빠르게 이동 (0) | 2020.11.26 |
---|---|
emacs에서 빈 파일을 어떻게 생성합니까? (0) | 2020.11.26 |
모든 항목을 바꿉니다. (0) | 2020.11.26 |
원격지가 전송 스트림을 닫았 기 때문에 인증에 실패했습니다. (0) | 2020.11.26 |
VS Code 통합 터미널의 색상 테마 (0) | 2020.11.26 |