web-dev-qa-db-ja.com

バッチファイルの変数から二重引用符を削除すると、CMD環境で問題が発生する

バッチ変数から引用符を削除する効果的かつ安全な方法で誰かが助けることができますか?

パラメータ%1、%2、%3などのリストを正常にインポートし、名前付き変数に配置するバッチファイルを作成しました。これらのパラメーターの一部には複数の単語が含まれているため、二重引用符で囲まれています。

> "Susie Jo" (%1)  
> "Smith Barnes" (%2)  
> "123 E. Main St." (%3)  

これらの%変数は、次に名前付き変数に配置されます

> set FirstName=%1  
> set LastName=%2  
> set ShipAddr=%3  

変数の検証はエコーによって行われます。

echo。%FirstName%
echo。%LastName%
echo。%ShipAddr%

結果は次のように表示されます

"Susie Jo"  
"Smith Barnes"  
"123 E. Main St."  

選択した変数に含まれる引用符を削除する必要があります。たとえば、FirstNameとLastNameは他の場所で使用され、引用符を含めることはできません。

テストバッチファイルでは、変数に〜チルダ文字を使用して引用符を削除することに成功しました。

> set FirstName=%~1
> set LastName=%~2 

私は解決策があると思っていましたが、すぐにバッチファイルの実行で異常な動作を経験しました。突然、CMDは長いパスの状態を認識しなくなりました。フルパスからのバッチファイルの通常の実行

> C:\Documents and Settings\Administrator\My Documents\Txt\batchtest\dataout.bat

返却値

> 'C:\Documents' is not recognized as an internal or external command....

そのため、着信%1%2 ...%n変数に〜チルダ文字を追加すると、何らかの変更が発生したように見えます。おそらくいくつかの環境変数が変更されていますか?

また、FORコマンドを使用してさまざまな試行を行い、変数内から引用符をクリアしようとしました。それは厄介なようで、タスクを実行する変数のリストを作成することでこれを達成する方法を学ぶことができませんでした:

このようなもの:

for %%g in (%FirstName% %LastName%) do (
set %%g=%%~g
set %%h=%%~h
set FirstName=%%~g
set LastName=%%h
echo.%FirstName% %LastName%
)

私には2つの問題があると思います。

1)着信%1%2変数(%〜1など)に〜チルダを挿入するという私の「短くて甘い」アイデアは、いくつかの設定に影響を与え、CMDが長いパス名をナビゲートする方法を変更したようです。

2)選択した名前付き変数から引用符を削除するためのクリーンで簡単な方法をまだ探しています。

より経験豊富な方へのご支援をいただければ幸いです。私はここで私のスキルの終わりにいます...いくつかのガイダンスが必要です!

編集12/26/2009 13:36 PSTバッチファイル全体:

ブロッククォート
:: dataout.bat
::リビジョン12/25/2009は、埋め込まれた「引用符を削除するために、着信%変数に〜チルダを追加します。
::コマンドラインパラメーターを使用してアドレスリストを書き込みます
:: QBooks IIFインポート用のデータ出力リストを書き込みます
:: RUIの販売者注文データを書き込みます
::テスト用のサンプルコマンドライン文字列
:: listmail [firstname] [lastname] ["address string"] ["city string"] [state] [Zip] [Order#] [PurchDate] [Regname] ["FirstName LastName"] [TransactionID ] [PaymentMethod] [Total] [ProductID] [Qty] [Price_Each] [PackPrep] [Shipping] [CommissionPmt] [Invoice#]
::例:dataout Bellewinkle Moose "123 Green Forest Way" "Vancouver" WA 98664 1004968 05/25/2009 "Bellewinkle Moose" "Olive Oyl" 101738 "On Account" 20.67 FK-1P 1 8.95 3.00 1.39 239
@ echo off
cls
c:
cd \
cd documents and settings\administrator\my documents\txt\batchtest
エコー処理%1%2
:バリセット
::%nコマンドラインパラメーターを文字列変数に変換します
set($ FirstName)=%〜1
set($ LastName)=%〜2
set($ BillingAddress1)=%〜3
set($ BillingCity)=%〜4
set($ BillingState)=%〜5
set($ BillingPostal)=%〜6
set($ OrderNumber)=%〜7
set($ Purch_Date)=%〜8
set($ RegistrationName)=%〜9
シフト
set($ TransactionID)=%〜9
シフト
set($ PaymentMethod)=%〜9
シフト
set($ Total)=%〜9
シフトセット($ ProductIdentifier)=%〜9
シフト
set($ Quantity)=%〜9
シフト
set($ Price_Each)=%〜9
シフト
set($ Pack_Prep)=%〜9
シフト
set($ Shipping)=%〜9
シフト
set($ ServiceFee)=%〜9
シフト
set($ Discount)=%〜9
シフト
set($ Invoice)=%〜9
シフト
set($ UnitPrice)=%〜9
set _ShipCombName =%($ FirstName)%%($ LastName)%
エコー船のコンボ名は%_ShipCombName%です
一時停止
::文字列変数をログファイルに書き込みます
echo FN%($ FirstName)%LN%($ LastName)%BA%($ BillingAddress1)%%($ BillingCity)%%($ BillingState)%%($ BillingPostal)%%($ OrderNumber) %%($ Purch_Date)%%($ RegistrationName)%%($ TransactionID)%%($ PaymentMethod)%%($ Total)%%($ ProductIdentifier)%%($ Quantity)%%($ Price_Each)%% ($ Pack_Prep)%%($ Shipping)%%($ ServiceFee)%%($ Discount)%%($ Invoice)%%($ UnitPrice)%%_ShipCombName%>> d_out_log.txt
::サービスプロバイダーによるアカウントの割り当て
IF/i%($ PaymentMethod)%== Amazon Receivables SET _QBAcct = Amazon.com
:: 12-25-2009は、汎用性のために2番目のAmazon pm'tメソッドを追加しました
IF/i%($ PaymentMethod)%== Amazon SET _QBAcct = Amazon.com
IF/i%($ PaymentMethod)%== MAST SET _QBAcct = Auth/Net
IF/i%($ PaymentMethod)%== MasterCard SET _QBAcct = Auth/Net
IF/i%($ PaymentMethod)%== Visa SET _QBAcct = Auth/Net
IF/i%($ PaymentMethod)%== Paypal SET _QBAcct = PayPalPmts
IF/i%($ PaymentMethod)%== On Account SET _QBAcct =%($ RegistrationName)%
IF/i%($ PaymentMethod)%== Mail SET _QBAcct =%($ RegistrationName)%
IF/i%($ PaymentMethod)%== AMER SET _QBAcct = Auth/Net
IF/i%($ PaymentMethod)%== DISC SET _QBAcct = Auth/Net
:: QBAccountに基づいて担当者を指定します
IF/i%($ PaymentMethod)%== Amazon Receivables SET _Rep = Amazon
:: 12-25-2009は、汎用性のために2番目のAmazon pm'tメソッドを追加しました
IF/i%($ PaymentMethod)%== Amazon SET _Rep = Amazon
IF/i%($ PaymentMethod)%== MAST SET _Rep = BlueZap
IF/i%($ PaymentMethod)%== MasterCard SET _Rep = BlueZap
IF/i%($ PaymentMethod)%== Visa SET _Rep = BlueZap
IF/i%($ PaymentMethod)%== Paypal SET _Rep = BlueZap
IF/i%($ PaymentMethod)%== On Account SET _Rep = R B
IF/i%($ PaymentMethod)%== Mail SET _Rep = R B
IF/i%($ PaymentMethod)%== AMER SET _Rep = BlueZap
IF/i%($ PaymentMethod)%== DISC SET _Rep = BlueZap
::住所データの重複を確認します
findstr/i/s "%_ShipCombName%" addrlist.txt
エコーエラーレベル:%errorlevel%
errorlevel 1 goto:ADDRWRITEの場合
errorlevel 0の場合goto:ADDRFOUND
:ADDRWRITE
echo%_ShipCombName%>> addrlist.txt
echo%($ BillingAddress1)%>> addrlist.txt
echo%($ BillingCity)%%($ BillingState)%%($ BillingPostal)%>> addrlist.txt
エコー。 >> addrlist.txt
エコーアドレスファイルの書き込み
:ADDRFOUND
選択した担当者のエコーは%_Rep%です
選択したアカウントのエコー:%_QBAcct%
一時停止
:: RUI OUT
:: Merchant Order IDとRUI Order IDをRUIに書き込みます
:: writeRUI.txtで重複したRUIデータをチェックします
cd ..
cd RegKOut
find/i "%($ OrderNumber)%" writeRUI.txt
エコーエラーレベル:%errorlevel%
errorlevel 1の場合goto:RUIWRITE
errorlevel 0の場合goto:IIFWRITE
:RUIWRITE
echo%($ Invoice)%%($ OrderNumber)%>> writeRUI.txt
:: RUIの書き込みを終了
:: IIF OUT
:IIFWRITE
:: writeIIF.txtで重複する請求書データを確認します
find/i "%($ OrderNumber)%" writeIIF.txt
エコーエラーレベル:%errorlevel%
errorlevel 1の場合goto:HEADWRITE
errorlevel 0の場合goto:LINEWRITE
:HEADWRITE
:: QB IIFインポートファイルへのヘッダー、出荷/処理、割引、担当者およびコミッションデータの書き込み
echo%($ OrderNumber)%%($ Purch_Date)%請求書%($ TransactionID)%%_QBAcct%売掛金%($ Total)%%_Rep%>> writeIIF.txt
エコーH/P%($ Pack_Prep)%1? >> writeIIF.txt
echo SHP%($ Shipping)%1? >> writeIIF.txt
echo DISC%($ Discount)%1? >> writeIIF.txt
echo Comm%($ ServiceFee)%1? >> writeIIF.txt
:LINEWRITE
IF/i%($ ProductIdentifier)%equ PH-1 goto WRITE_DEFA ELSE goto WRITE_DISC
echo%($ ProductIdentifier)%
:WRITE_DISC
::カスタム変数から解析された割引価格を書き込みます。
echo%($ ProductIdentifier)%%($ Price_Each)%%($ Quantity)%? >> writeIIF.txt
goto:EOF
:WRITE_DEFA
:製品データから解析されたデフォルト価格を書き込みます
echo%($ ProductIdentifier)%%($ UnitPrice)%%($ Quantity)%? >> writeIIF.txt
goto:EOF
:: 3秒の遅延
:: TYPE NUL | CHOICE.COM/N/CY/TY、3> NUL
:EOF

106
BobB

末尾に余分な二重引用符があります。これは、文字列から両方の引用符を削除した後、文字列の最後に追加します。

入力:

set widget="a very useful item"
set widget
set widget=%widget:"=%
set widget

出力:

widget="a very useful item"
widget=a very useful item

注:「二重引用符」を「単一引用符」に置き換えるには、次を実行します。

set widget=%widget:"='%

注:Wordの「World」(大文字と小文字を区別しない)をBobBに置き換えるには、次の手順を実行します。

set widget="Hello World!"
set widget=%widget:world=BobB%
set widget

出力:

widget="Hello BobB!"

最初の質問に関する限り(次のコードをバッチファイル.cmdまたは.batに保存して実行します)。

@ECHO OFF
ECHO %0
SET BathFileAndPath=%~0
ECHO %BathFileAndPath%
ECHO "%BathFileAndPath%"
ECHO %~0
ECHO %0
PAUSE

出力:

"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"
C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd
"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"
C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd
"C:\Users\Test\Documents\Batch Files\Remove Quotes.cmd"
Press any key to continue . . .

%0はスクリプト名とパスです。
%1は最初のコマンドライン引数などです。

182
Mr. Rick

あなたの結論(1)は間違っているように聞こえます。プレイには他の要因が必要です。

通常、バッチファイルパラメータの引用符の問題は、%~を使用して引用符を削除し、必要に応じて手動で戻すことで解決します。

例えば。:

set cmd=%~1
set params=%~2 %~3

"%cmd%" %params%

%cmd%を囲む引用符に注意してください。それらがないと、スペースを含むパスは機能しません。

バッチコード全体を投稿できる場合は、より具体的な回答を行うことができます。

38
atzz

これを簡単な方法で実行しようとして多くの時間を費やしました。 FORループを注意深く見て、1行のコードでこれを実現できることに気付きました。

FOR /F "delims=" %%I IN (%Quoted%) DO SET Unquoted=%%I

例:

@ECHO OFF
SET Quoted="Test string"

FOR /F "delims=" %%I IN (%Quoted%) DO SET Unquoted=%%I

ECHO %Quoted%
ECHO %Unquoted%

出力:

"Test string"
Test string
9

私は通常、変数からすべての引用符を削除するだけです:

set var=%var:"=%

そして、それらを必要な場所に再度適用します:

echo "%var%"
8
t1ck

私はこれから リンク を学びました。XP以上を使用している場合、これはそれ自体で単純に機能します:

SET params = %~1

ここでは、Windows 7で動作する他のソリューションを取得できませんでした。

それらを繰り返すために、私はこれをしました:

FOR %%A IN (%params%) DO (    
   ECHO %%A    
)

注:通常、スペースで区切られた引数を渡す場合にのみ、二重引用符を取得します。

3
user195488

これは、%〜を使用すべきでない場所で使用している単純なバグのように聞こえます。 %〜がバッチファイルの動作方法を根本的に変更しない場合の使用は、その単一の状況で文字列から引用符を削除するだけです。

3
John Knoeller

すべての回答が完了しました。しかし、一つだけ追加したかったのは、

firstName =%〜1を設定します

lastName =%〜2を設定

この行は機能しているはずで、小さな変更が必要です。

「FirstName =%〜1」を設定します

「LastName =%〜2」を設定します

割り当て全体を引用符で囲みます。問題なく引用符を削除します。これは、引数内の引用符での不要な問題を修正する割り当ての好ましい方法です。

0
Code Name Jack
@echo off

Setlocal enabledelayedexpansion

Set 1=%1

Set 1=!1:"=!

Echo !1!

Echo "!1!"

Set 1=

元のパラメーターに引用符があるかどうかに関係なく、引用符の有無にかかわらずデモを行います。

また、引用符で囲まれている場合とない場合があるパラメーターの存在をテストする場合は、上記のエコーの前に次の行を追加します。

'%1' == ''の場合yoursubに移動

ただし、引用符が付いている場合と付いていない場合があるファイルの存在を確認する場合は、次のようになります。

「!1!」が存在する場合goto othersub

単一引用符と二重引用符の使用が異なることに注意してください。

0
Aaron Lowe

私は解決策があると思っていましたが、すぐにバッチファイルの実行で異常な動作を経験しました。突然、CMDは長いパスの状態を認識しなくなりました。フルパスからのバッチファイルの通常の実行

C:\ Documents and Settings\Administrator\My Documents\Txt\batchtest\dataout.bat

返却値

「C:\ Documents」は、内部コマンドまたは外部コマンドとして認識されません。..

あなたの全体の問題があります。 CMDはコマンドラインからファイル名内のスペースを理解しないので、あなたがパスしようとしていると考えています

and Settings\Administrator\My Documents\Txt\batchtest\dataout.bat

へのパラメータとして

「C:\ Documents」

プログラム。

パスにスペースを含むバッチファイルを実行するには、引用符で囲む必要があります。

> "C:\Documents and Settings\Administrator\My Documents\Txt\batchtest\dataout.bat"

働いていただろう。

0
CarryWise
  1. 設定widget = "非常に便利なアイテム"
  2. ウィジェットを設定
  3. widget = "非常に便利なアイテム"
  4. 設定ウィジェット=%widget: "=%"
  5. ウィジェットを設定
  6. 設定ウィジェット=非常に便利なアイテム」

4行目の末尾の引用符"は、引用符"を文字列に追加しています。削除する必要があります。 4行目の構文は%で終わります

0
David