1

ファイルから行を読み込んでいるバッチ ファイルからコマンドを呼び出そうとしています。
行にリダイレクト文字が含まれている場合を除いて、これは正しく機能しています>

この文字をエスケープする方法call、または for ループの内容内で置き換える方法はありますか?

私はsetlocal enabledelayedexpansionand を見てきました(呼び出しが更新されて使用され!ても、まだ機能しません)。

set /p status=<%tmp_file%

for /f "delims=*" %%a in (%tmp_file%) do (
  echo "%%a"
  call check.bat "%%a"
  echo.

  if not "%errorlevel%" == "0" do exit /b 1
)

これにより、次の出力が生成されます(check.batエコーの場合%1

"a"
"a"

"b -> b"
"b -"

>内部で置き換えようとしました%%aが、これをどのように達成できるか完全にはわかりません。試行するたびに、空の文字列が生成されます。

set line=%a:^>=¬%

EDIT 1いくつかの明確化(変数に設定され、その変数が使用される
場合にのみ当てはまるようです)?%1

check.bat:

 set rawinput=%1
 set input=%~1

 echo %1
 echo "%rawinput%"
 echo "%input%"
 echo.

これにより、次の出力が得られます%1が、変数に設定すると値が壊れる理由がよくわかりません。

 "a"
 "a"
 ""a""
 "a"

 "b -> b"
 "b -> b"
 "b -"

興味深いことにb -> b、出力は 2 回だけで、echo "%rawinput%"まったく表示されません。echo "%input%"との両方echo "%rawinput%"が という名前のファイルに書き込んでいますb

これは、check.batforを次のb -> bように解釈する必要があることを意味します。

 echo "b -> b"
 echo ""b -> b""
 echo "b -> b"        REM - this is what 'should' be happening, however does appear to be the case, as it writes '' to a file named b
 echo.

echo "b -> b"バッチファイルで動作していないように見える理由を誰かが明らかにすることができれば、それは大歓迎です。

4

2 に答える 2

3

使用しようとしないでくださいcall by value、それはバッチではほとんど不可能です。
値を使用して新しい変数を設定し、変数名を使用するだけです。

for /f "delims=" %%a in (%tmp_file%) do (
  set "line=%%a"
  call :check
)
exit /b

:check
setlocal EnableDelayedExpansion
echo(!line!
endlocal
exit /b

編集:あなたの問題

"b -> b"これを使用してコンテンツで関数を呼び出そうとすると、
call check.bat "%%a"に展開され
call check.bat ""b -> b""、それが問題になります。
リダイレクト文字が引用符の外にあるため>、check.batの出力をファイルにリダイレクトしますb
呼び出しを使用するときに特殊文字(引用符の外)をエスケープできますが、これは少し高度であり、多くの問題があります。

したがって、通話でコンテンツを直接使用するのではなく、もう一度お勧めします。
次のような参照を使用できます

for /f "delims=" %%a in (%tmp_file%) do (
  set "line=%%a"
  call :check line
)

check.bat

setlocal EnableDelayedExpansion
set "var=!%1!"
echo(!var!
于 2012-11-19T14:38:14.753 に答える
2

変更した check.bat に複数の問題があります

引用符は、最初の引用符が引用セマンティクスをオンにし、2 番目がオフになり、3 番目がオンになるなどのステート マシン>です。

何が起こっているのかを説明するために一連の ECHO ステートメントを挿入することで、check.bat を大幅に変更しました。あなたの元のコードは、すべて大文字で私のバージョンに埋め込まれています。

これが私の修正版の出力です。結果が得られた理由が説明されていることを願っています。私の変更した check.bat がこの出力をどのように生成するかを理解する前に、この出力を読んでください。

"a"
---------------------------------------------
Executing: SET RAWINPUT=%1  which expands to  SET RAWINPUT="a"
Here is the result:
rawinput="a"

Executing: SET INPUT=%~1  which expands to  SET INPUT=a
Here is the result:
input=a

Executing: ECHO %1  which expands to  ECHO "a"
"a"

Executing: ECHO "%RAWINIPUT%"  which expands to  ECHO ""a""
""a""

Executing: ECHO "%INPUT%"  which expands to  ECHO "a"
"a"


"b -> b"
---------------------------------------------
Executing: SET RAWINPUT=%1  which expands to  SET RAWINPUT="b -> b"
Here is the result:
rawinput="b -> b"

Executing: SET INPUT=%~1  which expands to  SET INPUT=b -> b
Here is the result:
input=b -

Also created a file named "b" because the output of the command
is redirected. The file is empty because SET has no output.

 Volume in drive C is OS
 Volume Serial Number is EE2C-5A11

 Directory of C:\Users\Public\utils

11/20/2012  09:30 AM                 0 b
               1 File(s)              0 bytes
               0 Dir(s)  316,104,765,440 bytes free

Executing: ECHO %1  which expands to  ECHO "b -> b"
"b -> b"

Executing: ECHO "%RAWINIPUT%"  which expands to  ECHO ""b -> b""

There is no screen output because output was redirected to file "b"
Here are the contents of "b":
""b -

Executing: ECHO "%INPUT%"  which expands to  ECHO "b -"
"b -"

上記の出力を生成する変更した check.bat を次に示します。

setlocal enableDelayedExpansion
set value=%1
set "unquotedValue=%~1"

echo ---------------------------------------------
echo Executing: SET RAWINPUT=%%1  which expands to  SET RAWINPUT=!value!
SET RAWINPUT=%1
echo Here is the result:
set rawinput
echo.

echo Executing: SET INPUT=%%~1  which expands to  SET INPUT=!unquotedValue!
SET INPUT=%~1
echo Here is the result:
set input
if exist b (
  echo.
  echo Also created a file named "b" because the output of the command
  echo is redirected. The file is empty because SET has no output.
  echo.
  dir b
  del b
)
echo.

echo Executing: ECHO %%1  which expands to  ECHO !value!
ECHO %1
echo.

echo Executing: ECHO "%%RAWINIPUT%%"  which expands to  ECHO "!rawinput!"
ECHO "%RAWINPUT%"
if exist b (
  echo.
  echo There is no screen output because output was redirected to file "b"
  echo Here are the contents of "b":
  type b
  del b
)
echo.

echo Executing: ECHO "%%INPUT%%"  which expands to  ECHO "!input!"
ECHO "%INPUT%"
echo.


check.batに引用符を追加しない場合、変数を介して目的の結果を得ることができます

set rawinput=%1
echo %rawinput%

しかし、元のテキスト ファイルに独自の引用符が含まれていると、最悪の事態が発生する可能性があります。

これが、jeb が各行をメイン ルーチン内の変数に格納し、変数の名前を check.bat に渡すことを提案している理由です。check.bat 内では、遅延展開を使用して、引用符やエスケープを気にすることなく、任意の値を安全に操作できます。

于 2012-11-20T14:45:44.720 に答える