Loại bỏ dấu ngoặc kép khỏi các biến trong tệp loạt sẽ tạo ra sự cố với môi trường CMD


116

Ai có thể giúp đỡ với cách hiệu quả và an toàn để loại bỏ dấu ngoặc kép từ các biến hàng loạt không?

Tôi đã viết một tệp lô nhập thành công danh sách các tham số% 1,% 2,% 3, v.v. và đặt chúng vào các biến được đặt tên. Một số tham số này chứa nhiều từ và được đặt trong dấu ngoặc kép.

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

Các biến% này được đặt tiếp theo trong các biến có tên:

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

xác minh các biến được thực hiện bằng echo.

echo.% FirstName%
echo.% LastName%
echo.% ShipAddr%

kết quả hiển thị dưới dạng

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

Tôi cần loại bỏ các dấu ngoặc kép trên các biến đã chọn. Ví dụ: FirstName và LastName được sử dụng ở nơi khác và không được bao gồm dấu ngoặc kép.

Trong một tệp lô thử nghiệm, tôi đã thành công khi loại bỏ dấu ngoặc kép bằng ký tự dấu ngã ~ trong các biến.

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

Tôi nghĩ rằng tôi đã có giải pháp, nhưng tôi sớm gặp phải hành vi bất thường khi thực thi các tệp hàng loạt. Đột nhiên CMD không nhận ra trạng thái đường dẫn dài. Thực hiện bình thường tệp hàng loạt từ đường dẫn đầy đủ

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

trả lại

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

Vì vậy, có vẻ như việc thêm ký tự dấu ngã ~ vào các biến% 1% 2 ...% n sắp tới đã gây ra một số thay đổi. Có thể một số biến môi trường đã bị thay đổi?

Tôi cũng đã thử xóa dấu ngoặc kép từ bên trong biến bằng nhiều lần thử bằng lệnh FOR. Điều đó có vẻ khó xử và tôi đã không thể học cách thực hiện điều này bằng cách tạo danh sách các biến để thực hiện tác vụ:

một cái gì đó như thế này:

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

Tôi nghĩ tôi có hai vấn đề.

1) Ý tưởng 'ngắn gọn và thú vị' của tôi về việc chèn ~ dấu ngã trong các biến% 1% 2 (% ~ 1, v.v.) đến dường như đã ảnh hưởng đến một số cài đặt và thay đổi cách CMD điều hướng các tên đường dẫn dài.

2) Tôi vẫn đang tìm kiếm một cách sạch sẽ và dễ dàng để loại bỏ dấu ngoặc kép khỏi các biến được đặt tên đã chọn.

Bất kỳ sự giúp đỡ nào cho những người có kinh nghiệm hơn sẽ được đánh giá cao nhất. Tôi đang ở cuối các kỹ năng của tôi ở đây ... cần một số hướng dẫn!

chỉnh sửa 26/12/2009 13:36 PST toàn bộ tệp loạt:

Blockquote
:: dataout.bat :: rev 12/25/2009
add ~ dấu ngã vào các biến% đến để loại bỏ dấu ngoặc kép "nhúng.
:: ghi danh sách địa chỉ bằng cách sử dụng tham số dòng lệnh
:: ghi danh sách đầu ra dữ liệu cho QBooks IIF import
:: write Dữ liệu đơn đặt hàng của người bán cho RUI
:: chuỗi dòng lệnh mẫu để thử nghiệm
:: 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 #]
:: example: dataout Bellewinkle Moose "123 Green Forest Way" "Vancouver" WA 98664 1004968 25/05/2009 "Bellewinkle Moose" "Olive Oyl" 101738 "Trên tài khoản" 20,67 FK-1P 1 8,95 3,00 1,39 239
@echo off
cls
c:
cd \
cd tài liệu và cài đặt \ quản trị viên \ tài liệu của tôi \ txt \ batchtest
echo xử lý% 1% 2
: VARISET
::Chuyển đổi% n tham số dòng lệnh thành biến chuỗi
được đặt ($ FirstName) =% ~ 1
set ($ LastName) =% ~ 2
set ($ BillingAddress1) =% ~ 3
set ($ BillingCity) =% ~ 4
set ($ BillingState) =% ~ 5
bộ ($ BillingPostal) =% ~ 6
bộ ($ OrderNumber) =% ~ 7
bộ ($ Purch_Date) =% ~ 8
bộ ($ Tên đăng ký) =% ~ 9

bộ ca ($ TransactionID) =% ~ 9 bộ
ca
($ PaymentMethod) =% ~ 9 bộ
ca
(Tổng số tiền $) =% ~ 9
bộ ca ($ ProductIdentifier) ​​=% ~ 9 bộ
ca
($ Số lượng) =% ~ 9 bộ
ca
($ Price_Each) =% ~ 9
ca
($ Pack_Prep) =% ~ 9
ca
($ Vận chuyển) =% ~ 9
ca
($ ServiceFee) =% ~ 9
ca
(Giảm giá $) =% ~ 9
shift
set ($ Invoice) =% ~ 9
shift
set ($ UnitPrice) =% ~ 9
set _ShipCombName =% ($ FirstName)%% ($ LastName)%
echo ship tổ hợp tên là% _ShipCombName%
tạm dừng
:: ghi biến chuỗi vào logfile
echo FN% ($ FirstName)% LN% ($ LastName)% BA% ($ BillingAddress1)%% ($ BillingCity)%% ($ BillingState)%% ($ BillingPostal)%% ($ OrderNumber)%% ($ Purch_Date)%% ($ RegisterName)%% ($ TransactionID)%% ($ PaymentMethod)%% ($ Total)%% ($ ProductIdentifier)%% ($ Quantity)%% ($ Price_Each) %% ($ Pack_Prep)%% ($ Vận chuyển)%% ($ ServiceFee)%% ($ Giảm giá)%% ($ Hóa đơn)%% ($ UnitPrice)%% _ShipCombName% >> d_out_log.txt
:: Chỉ định tài khoản bởi Nhà cung cấp dịch vụ
IF / i% ($ PaymentMethod)% == Amazon Receivables SET _QBAcct = Amazon.com
:: 12-25-2009 đã thêm phương thức Amazon pm't thứ hai cho tính linh hoạ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)% == Trên tài khoản SET _QBAcct =% ($ RegisterName)%
IF / i% ($ PaymentMethod)% == Mail SET _QBAcct =% ($ RegisterName)%
IF / i% ( $ PaymentMethod)% == AMER SET _QBAcct = Auth / Net
IF / i% ($ PaymentMethod)% == DISC SET _QBAcct = Auth / Net
:: Chỉ định người đại diện dựa trên QBAccount
IF / i% ($ PaymentMethod)% == Amazon Receivables SET _Rep = Amazon
:: 12-25-2009 đã thêm phương thức Amazon pm't thứ hai cho tính linh hoạ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)% == Trên Account SET _Rep = RB
IF / i% ($ PaymentMethod)% == Mail SET _Rep = RB
IF / i% ($ PaymentMethod)% == AMER SET _Rep = BlueZap
IF / i % ($ PaymentMethod)% == DISC SET _Rep = BlueZap
:: kiểm tra dữ liệu địa chỉ trùng lặp
findstr / i / s "% _ShipCombName%" addrlist.txt
echo errorlevel:% errorlevel%
if errorlevel 1 goto: ADDRWRITE
if errorlevel 0 goto: ADDRFOUND
: ADDRWRITE
echo% _ShipCombName% >> addrlist.txt
echo% ($ BillingAddress1)% >> addrlist.txt
echo% ($ BillingCity)%% ($ BillingState)%% ($ BillingPostal)% >> addrlist.txt
echo. >> addrlist.txt
echo Địa chỉ Tệp Đã viết
: ADDRFOUND
echo đã chọn đại diện là% _Rep%
echo đã chọn tài khoản là:% _QBAcct%
pause
:: RUI OUT
:: ghi ID đơn đặt hàng của người bán & ID đặt hàng RUI thành RUI
:: kiểm tra dữ liệu RUI trùng lặp trong writeRUI.txt
cd ..
cd RegKOut
find / i "% ($ OrderNumber)%" writeRUI.txt
echo errorlevel:% errorlevel%
if errorlevel 1 goto: RUIWRITE
if errorlevel 0 goto: IIFWRITE
: RUIWRITE
echo% ($ Invoice)% % ($ OrderNumber)% >> writeRUI.txt
:: end ghi RUI
:: IIF OUT
: IIFWRITE
:: Kiểm tra dữ liệu hóa đơn trùng lặp trong writeIIF.txt
find / i "% ($ OrderNumber)%" writeIIF.txt
echo errorlevel:% errorlevel%
if errorlevel 1 goto: HEADWRITE
if errorlevel 0 goto: LINEWRITE
: HEADWRITE
:: write Dữ liệu tiêu đề, Giao hàng / Xử lý, chiết khấu, Đại diện & hoa hồng vào tệp nhập QB IIF
echo% ($ OrderNumber)% ($ Purch_Date)% Invoice% ($ TransactionID)%% _QBAcct% Khoản phải thu% ($ Total)%% _Rep % >> writeIIF.txt
echo H / P% ($ Pack_Prep)% 1? >> writeIIF.txt
echo SHP% ($ Vận chuyển)% 1? >> writeIIF.txt
echo DISC% ($ Giảm giá)% 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
:: ghi giá chiết khấu được phân tích cú pháp từ biến tùy chỉnh:
echo% ($ ProductIdentifier) %% ($ Giá_Each)%% ($ Số lượng)%? >> writeIIF.txt
goto: EOF
: WRITE_DEFA
: ghi giá mặc định được phân tích cú pháp từ Dữ liệu sản phẩm
echo% ($ ProductIdentifier)%% ($ UnitPrice)%% ($ Quantity)%? >> writeIIF.txt
goto: EOF
:: Độ trễ 3 giây
:: TYPE NUL | CHOICE.COM / N / CY / TY, 3> NUL
: EOF


Bạn có thể sử dụng PowerShell để thực hiện việc này không? Tôi nghi ngờ bạn sẽ kiểm soát nhiều hơn một chút nếu bạn sử dụng PowerShell.
Robert Harvey

1
Tôi đã kiểm tra tệp hàng loạt của bạn - nó có vẻ hoạt động tốt (sau khi tôi sửa dòng "shift set ($ ProductIdentifier) ​​=% ~ 9" - theo tôi, là một tác phẩm của việc sao chép và dán nó ở đây).
atzz

Cảm ơn Robert Harvey; Tôi đã xem xét PowerShell. Tôi không có nhiều kinh nghiệm về lập trình .. không chắc đường cong học tập sẽ như thế nào. Tôi có một số kinh nghiệm với các tệp hàng loạt, lý do chính khiến tôi chọn điều này. Tôi đang có ý định biên dịch lô để nó chạy nhanh hơn. Cảm ơn cho phản ứng.
BobB

Cảm ơn atzz: Kể từ đó tôi đã thử nghiệm tệp hàng loạt này thêm một số lần nữa và tôi hoàn toàn tin tưởng rằng dấu ngoặc kép ~ dấu ngã và dấu ngoặc kép không liên quan đến vấn đề CMD với tên đường dẫn dài. Tôi đã giải quyết vấn đề đó bằng cách thiết lập một thư mục con tên ngắn gần với thư mục gốc để loại bỏ các tên đường dẫn dài.
BobB

Không cần hiển thị toàn bộ tập tin hàng loạt. Vui lòng rút ngắn câu hỏi của bạn.
Jor

Câu trả lời:


192

Bạn có thêm một dấu ngoặc kép ở cuối, tức là thêm dấu ngoặc kép vào cuối chuỗi (sau khi xóa cả hai dấu ngoặc kép khỏi chuỗi).

Đầu vào:

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

Đầu ra:

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

Lưu ý: Để thay thế Dấu ngoặc kép "bằng Dấu ngoặc kép", hãy làm như sau:

set widget=%widget:"='%

Lưu ý: Để thay thế từ "Thế giới" (không phân biệt chữ hoa chữ thường) bằng BobB, hãy làm như sau:

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

Đầu ra:

widget="Hello BobB!"

Theo như câu hỏi ban đầu của bạn (lưu mã sau vào tệp loạt .cmd hoặc .bat và chạy):

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

Đầu ra:

"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 . . .

%0là Tên tập lệnh và Đường dẫn.
%1là đối số dòng lệnh đầu tiên, v.v.


Cảm ơn, đây là điều mà tôi đã sau SET BathFileAndPath=%~0(trên thực tế, param tôi mảng bắt đầu với 1 vì vậy tôi sử dụngSET BathFileAndPath=%~1
Valamas

Bạn có thể giải thích tại sao lại %widget:"=%loại bỏ dấu ngoặc kép?
CodyBugstein

4
@Imray - :old=newlà một đối sánh và thay thế mẫu trong phần mở rộng biến. Với "as the oldvà nothing as the new, các dấu ngoặc kép bị loại bỏ, ngay cả khi chúng ở giữa, ngay cả khi chúng không cân bằng.
Jesse Chisholm

thiết lập Widget =% phụ tùng: "=% có hành vi kỳ lạ khi widget là trống, nó sẽ trả "="
Rahul Misra

43

Kết luận của bạn (1) nghe có vẻ sai. Phải có một số yếu tố khác khi chơi.

Vấn đề về dấu ngoặc kép trong các tham số tệp hàng loạt thường được giải quyết bằng cách xóa dấu ngoặc kép %~và sau đó đặt chúng trở lại thủ công nếu thích hợp.

Ví dụ:

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

"%cmd%" %params%

Lưu ý các báo giá xung quanh %cmd%. Nếu không có chúng, đường dẫn có dấu cách sẽ không hoạt động.

Nếu bạn có thể đăng toàn bộ mã hàng loạt của mình, có thể có câu trả lời cụ thể hơn.


1
Tôi đồng ý; có vẻ như với tôi tập hợp var =% ~ 1 sẽ hoạt động tốt. Tôi sẽ đăng toàn bộ tệp hàng loạt theo yêu cầu.
BobB

Tham khảo MS: Sử dụng các tham số lô . Ai biết có rất nhiều bổ ngữ? Để tham khảo, MS doc chính thức cung cấp cho các mô tả về %~1nhưExpands %1 and removes any surrounding quotation marks ("").
cod3monk3y

@ cod3monk3y Ngoài ra, bạn có thể cmdtự hỏi về các công cụ sửa đổi này: call /?để được trợ giúp về công cụ sửa đổi tham số, set /?về công cụ sửa đổi biến (có thể không trực quan lắm). Khá tiện dụng.
atzz

12

Tôi thường chỉ xóa tất cả các dấu ngoặc kép khỏi các biến của mình với:

set var=%var:"=%

Và sau đó áp dụng chúng một lần nữa bất cứ nơi nào tôi cần, ví dụ:

echo "%var%"

Tôi cũng gặp rắc rối với điều này lúc đầu, hóa ra tôi đã xem :như là một .- sau khi tìm ra điều đó, hoạt động mà không gặp trở ngại. Mẹo hay!
DaveU

9

Đã dành nhiều thời gian để cố gắng làm điều này một cách đơn giản. Sau khi xem xét cẩn thận vòng lặp FOR, tôi nhận ra rằng mình có thể thực hiện việc này chỉ với một dòng mã:

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

Thí dụ:

@ECHO OFF
SET Quoted="Test string"

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

ECHO %Quoted%
ECHO %Unquoted%

Đầu ra:

"Test string"
Test string

Phương pháp này không liên quan trong khi "SET Trích dẫn = Chuỗi kiểm tra". Câu hỏi tiếp theo là làm thế nào để khác biệt không "(double quote) tồn tại hay không cho ai có thể có liên quan, cảm ơn bạn ở cao cấp..
Rhak Kahr

3

Điều này nghe có vẻ giống như một lỗi đơn giản khi bạn đang sử dụng% ~ ở một nơi mà bạn không nên ở đó. Việc sử dụng if% ~ về cơ bản không thay đổi cách thức hoạt động của các tệp hàng loạt, nó chỉ xóa dấu ngoặc kép khỏi chuỗi trong tình huống đơn lẻ đó.


3

Tôi đã học được từ liên kết này , nếu bạn đang sử dụng XP trở lên, điều này sẽ đơn giản tự hoạt động:

SET params = %~1

Tôi không thể nhận được bất kỳ giải pháp nào khác ở đây để hoạt động trên Windows 7.

Để lặp lại chúng, tôi đã làm như sau:

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

Lưu ý: Bạn sẽ chỉ nhận được dấu ngoặc kép nếu bạn truyền các đối số được phân tách bằng dấu cách thường.


0
  1. đặt widget = "một mục rất hữu ích"
  2. thiết lập tiện ích
  3. widget = "một vật phẩm rất hữu ích"
  4. đặt widget =% widget: "=%"
  5. thiết lập tiện ích
  6. đặt widget = một mục rất hữu ích "

Dấu ngoặc kép "ở dòng 4 là thêm dấu ngoặc kép "vào chuỗi. Nó nên được loại bỏ. Cú pháp cho dòng 4 kết thúc bằng%


@ user195488 - đọc dòng 3 khi quan sát thấy nó hiển thị:widget="a very useful item" và đọc dòng 6 khi quan sát nó hiển thị:widget=a very useful item" và hiểu rằng dòng 7 sẽ là set widget=%widget:"=%và dòng 8 sẽ được quan sát rằng dòng được hiển thị widget=a very useful itemkhông còn dấu ngoặc kép .
Jesse Chisholm

0

Tôi nghĩ rằng tôi đã có giải pháp, nhưng tôi sớm gặp phải hành vi bất thường khi thực thi các tệp hàng loạt. Đột nhiên CMD không nhận ra trạng thái đường dẫn dài. Thực hiện bình thường tệp hàng loạt từ đường dẫn đầy đủ

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

trả lại

'C: \ Documents' không được nhận dạng là lệnh nội bộ hoặc lệnh bên ngoài ....

Có toàn bộ vấn đề của bạn. CMD không hiểu khoảng trống bên trong tên tệp từ dòng lệnh, vì vậy nó nghĩ rằng bạn đang cố gắng chuyển

và Cài đặt \ Quản trị viên \ Tài liệu của Tôi \ Txt \ batchtest \ dataout.bat

như các tham số cho

"C: \ Documents"

chương trình.

Bạn cần phải trích dẫn nó để chạy một tệp hàng loạt có khoảng trắng trong đường dẫn:

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

sẽ có hiệu quả.


0
@echo off

Setlocal enabledelayedexpansion

Set 1=%1

Set 1=!1:"=!

Echo !1!

Echo "!1!"

Set 1=

Thể hiện có hoặc không có dấu ngoặc kép mà không cần biết tham số gốc có dấu ngoặc kép hay không.

Và nếu bạn muốn kiểm tra sự tồn tại của một tham số có thể có hoặc có thể không trong dấu ngoặc kép, hãy đặt dòng này trước phần lặp lại ở trên:

If '% 1' == '' goto yourub

Nhưng nếu kiểm tra sự tồn tại của một tệp có thể có hoặc không có dấu ngoặc kép thì đó là:

Nếu TỒN TẠI "! 1!" goto othersub

Lưu ý việc sử dụng dấu nháy đơn và dấu nháy kép là khác nhau.


0

Tất cả các câu trả lời đã hoàn thành. Nhưng muốn thêm một điều,

đặt FirstName =% ~ 1

đặt LastName =% ~ 2

Dòng này lẽ ra đã hoạt động, bạn cần một thay đổi nhỏ.

đặt "FirstName =% ~ 1"

đặt "LastName =% ~ 2"

Bao gồm bài tập hoàn chỉnh trong dấu ngoặc kép. Nó sẽ xóa dấu ngoặc kép mà không có vấn đề gì. Đây là một cách chỉ định được ưa chuộng để khắc phục các vấn đề không mong muốn với dấu ngoặc kép trong đối số.


0

Cú pháp dấu ngã đơn giản chỉ hoạt động để xóa dấu ngoặc kép xung quanh các tham số dòng lệnh được chuyển vào tệp lô

SET xyz=%~1

Mã tệp lô ở trên sẽ đặt xyz thành bất kỳ giá trị nào đang được chuyển dưới dạng tham số đầu tiên loại bỏ các trích dẫn đầu và cuối (nếu có).

Tuy nhiên, cú pháp dấu ngã đơn giản này sẽ không hoạt động đối với các biến khác không được chuyển vào dưới dạng tham số

Đối với tất cả các biến khác, bạn cần sử dụng cú pháp thay thế mở rộng yêu cầu bạn chỉ định các ký tự đầu và ký tự tụt hậu cần được xóa. Một cách hiệu quả, chúng tôi hướng dẫn xóa bỏ ký tự đầu tiên và ký tự cuối cùng mà không cần xem nó thực sự là gì.

@SET SomeFileName="Some Quoted file name"
@echo %SomeFileName% %SomeFileName:~1,-1%

Nếu chúng tôi muốn kiểm tra ký tự đầu tiên và ký tự cuối cùng thực sự là gì trước khi xóa nó, chúng tôi sẽ cần một số mã bổ sung như sau

@SET VAR="Some Very Long Quoted String"
If aa%VAR:~0,1%%VAR:~-1%aa == aa""aa SET UNQUOTEDVAR=%VAR:~1,-1%
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.