4

Windows バッチ ファイルで次のコードを実行すると、スキップされるアスタリスクを含む文字列以外はすべて機能します。渡されたパラメーターを番号で確認すると (つまりecho(%~6)、アスタリスクが表示されます。問題があるのは、FOR ループに渡された場合のみです。

@echo off
setlocal enableextensions enabledelayedexpansion
call:Concat cmd "this is a demo" " of concat functionality." " Hopefully it will work;" " but it doesn't when I pass an" " * asterisk" " character"
echo !cmd!

@goto:end
@goto:eof


:Concat
::Concatenates a given list of strings without including their quotes
::1 - output variable
::2* - strings to concat
echo(%*
set /a xx=0
set Concat_tempFlag=0
set Concat_temp=
for %%A in (%*) do (
    set /a xx=!xx!+1
    echo !xx! - %%A
    if !Concat_tempFlag!==1 (
        set Concat_temp=!Concat_temp!%%~A
    ) else (
        set Concat_tempFlag=1
    )
)
set "%~1="%Concat_temp%""
@goto:eof

:End
echo(Bye
exit /b 0

for /F (tokens=*) %%A in ('echo(%*') do (ここで提案されているように試みました:アスタリスク(およびそのバリエーション)を使用したバッチFORループですが、運がありません。何か案は?前もって感謝します。

4

2 に答える 2

6

ここで解決策を見つけました:ネイティブの Windows コマンドのみを使用して、バッチ環境変数のアスタリスク * を一致または置換する必要があります。これは可能ですか?

以下の完全なコード:

@echo off
setlocal enableextensions enabledelayedexpansion
set DEFAULT_AsteriskMarker=_xAsteriskMarkerx_
call:Concat cmd "this is a demo" " of concat functionality." " Hopefully it will work;" " but it doesn't when I pass an" " * asterisk" " character"
echo !cmd!

@goto:end
@goto:eof


:Concat
::Concatenates a given list of strings without including their quotes
::1 - output variable
::2* - strings to concat
set Concat_StringsToConcat=%*
echo(%Concat_StringsToConcat%
call:AsteriskFix Concat_StringsToConcat
set /a xx=0
set Concat_tempFlag=0
set Concat_temp=
for %%A in (%Concat_StringsToConcat%) do (
    set /a xx=!xx!+1
    echo !xx! - %%A
    if !Concat_tempFlag!==1 (
        set Concat_temp=!Concat_temp!%%~A
    ) else (
        set Concat_tempFlag=1
    )
)
set "%~1="!Concat_temp:%DEFAULT_AsteriskMarker%=*!"
@goto:eof

:AsteriskFix
::https://stackoverflow.com/questions/11685375/i-need-to-match-or-replace-an-asterisk-in-a-batch-environmental-variable-using
set AsteriskFix_temp=!%~1!
if "%~2"=="" (
    set AsteriskFix_marker=%DEFAULT_AsteriskMarker%
) else (
    set AsteriskFix_marker=%~2
)
call:StrLen AsteriskFix_temp AsteriskFix_len
for /l %%x in (0,1,%AsteriskFix_len%) do if not "!AsteriskFix_temp:~%%x,1!"=="" if "!AsteriskFix_temp:~%%x,1!"=="*" (
    set /a AsteriskFix_plusone=%%x+1
    for /l %%y in (!AsteriskFix_plusone!, 1, !AsteriskFix_plusone!) do (
        set AsteriskFix_temp=!AsteriskFix_temp:~0,%%x!%AsteriskFix_marker%!AsteriskFix_temp:~%%y!
    )
)
set "%~1=!AsteriskFix_temp!"
@goto:eof

:StrLen
::http://www.dostips.com/DtCodeCmdLib.php#strLen
set "StrLen_str=A!%~1!"            &:: keep the A up front to ensure we get the length and not the upper bound
                                 ::it also avoids trouble in case of empty string
set "StrLen_len=0"
for /L %%A in (12,-1,0) do (
    set /a "StrLen_len|=1<<%%A"
    for %%B in (!StrLen_len!) do if "!StrLen_str:~%%B,1!"=="" set /a "StrLen_len&=~1<<%%A"
)
IF "%~2" NEQ "" SET /a %~2=%StrLen_len%
@goto:eof

:End
echo(Bye
exit /b 0

ジェームスKに感謝

于 2013-06-13T12:41:09.190 に答える
4

あなたが提供したリンクは正しい答えにつながります:

通常の (/F オプションなし) FOR コマンドのセットでアスタリスク (または疑問符) を保持する方法はありません (それらは常にファイル名に変更されます)。FOR /F コマンドでパラメーターを区切る必要があります。FOR ループ内の各パラメーターも処理する場合、2 番目の FOR は同じコンテキスト内にあることはできないため、サブルーチンを呼び出してコンテキストを変更する必要があります。

于 2013-06-12T18:26:01.983 に答える