Cách tốt nhất để làm một chuỗi con trong một tệp bó là gì?


192

Tôi muốn lấy tên của tệp hiện đang chạy mà không cần phần mở rộng tệp.

Nhờ liên kết này , tôi có tên tệp phần mở rộng ... nhưng cách tốt nhất để thực hiện một chuỗi con trong tệp bó là gì?

Hoặc có một cách khác để có được tên tập tin với phần mở rộng?

Sẽ an toàn khi giả sử 3 phần mở rộng chữ cái trong kịch bản này.

Câu trả lời:


395

Chà, để có được tên tệp của đợt của bạn, cách dễ nhất là sử dụng %~n0.

@echo %~n0

sẽ xuất tên (không có phần mở rộng) của tệp bó hiện đang chạy (trừ khi được thực thi trong chương trình con được gọi bởi call). Có thể tìm thấy danh sách đầy đủ các thay thế đặc biệt của nhóm đối với các tên đường dẫn khác help for, ở phần cuối của trợ giúp:

Ngoài ra, việc thay thế các tham chiếu biến FOR đã được tăng cường. Bây giờ bạn có thể sử dụng cú pháp tùy chọn sau:

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file
%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string

Các sửa đổi có thể được kết hợp để có được kết quả gộp:

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only

Tuy nhiên, để trả lời chính xác câu hỏi của bạn: Các phần con được thực hiện bằng cách sử dụng :~start,lengthký hiệu:

%var:~10,5%

sẽ trích xuất 5 ký tự từ vị trí 10 trong biến môi trường %var%.

GHI CHÚ: Chỉ số của các chuỗi là 0 dựa, vì vậy ký tự đầu tiên ở vị trí 0, thứ hai ở 1, v.v.

Để có được chuỗi con của các biến lập luận như %0, %1vv bạn phải gán chúng vào một biến môi trường bình thường sử dụng setđầu tiên:

:: Does not work:
@echo %1:~10,5

:: Assign argument to local variable first:
set var=%1
@echo %var:~10,5%

Cú pháp thậm chí còn mạnh mẽ hơn:

  • %var:~-7% trích xuất 7 ký tự cuối cùng từ %var%
  • %var:~0,-4%sẽ trích xuất tất cả các ký tự ngoại trừ bốn ký tự cuối cùng cũng sẽ loại bỏ phần mở rộng tệp của bạn (giả sử ba ký tự sau dấu chấm [ .]).

Xem help setđể biết chi tiết về cú pháp đó.


31
Trích xuất chuỗi con không hoạt động với các biến vòng lặp FOR, do đó bạn sẽ phải thực hiện như sau (\ r \ n trong mã có nghĩa là ngắt dòng vì SO dường như không cho phép ngắt dòng trong các nhận xét):setlocal ENABLEDELAYEDEXPANSION \r\n for /f %%s in ('set') do ( \r\n set tmp=%%s \r\n echo !tmp:~-3! \r\n )
Fr0sT

@ Fr0sT tại sao bạn phải làm điều này cho FORcác vòng lặp?
Bob

4
@Adrian tại sao không? FORlà một cấu trúc nền tảng trong các tệp bó thực hiện số lượng khá lớn các nhiệm vụ khác nhau. Btw, có thêm một cách để đối phó với nhiệm vụ bằng cách sử dụng chương trình con, tức làfor /f %%s in ('set') do call :DoSmth "%%s" \r\n ... \r\n :DoSmth \r\n set var=%1 \r\n echo %var:~1,3%
Fr0sT

1
sử dụng máy chủ windows 12 R2,% ngày% trông giống như 21/05/18 (văn hóa CNTT); chuỗi bên phải là: %date:~0,2%%date:~3,2%%date:~6,4%%time:~0,2%%time:~3,2%%time:~6,2%
Phate01

@ Phate01, không sử dụng %date%để tạo một ngày theo một định dạng nhất định. Định dạng dành riêng cho văn hóa người dùng và có thể thay đổi. Thay vào đó, hãy sử dụng WMI để nhận ngày và giờ ở định dạng hữu ích không phụ thuộc vào cài đặt của người dùng. Ngoài ra tôi không chắc nhận xét này đang làm gì ở đây, vì câu hỏi này không phải là về ngày hay thời gian.
Joey

38

Giải thích rõ ràng ở trên!

Đối với tất cả những người có thể đau khổ như tôi để làm việc này trong Windows được bản địa hóa (của tôi là XP bằng tiếng Slovak), bạn có thể thử thay thế %bằng một!

Vì thế:

SET TEXT=Hello World
SET SUBSTRING=!TEXT:~3,5!
ECHO !SUBSTRING!

27
Lưu ý rằng điều này sẽ chỉ hoạt động sau khi setlocal ENABLEDELAYEDEXPANSIONlệnh
Fr0sT

13

Là một thông tin bổ sung cho câu trả lời của Joey, không được mô tả trong phần trợ giúp của set /?cũng không for /?.

%~0mở rộng thành tên của lô riêng, chính xác như nó đã được gõ.
Vì vậy, nếu bạn bắt đầu lô của mình, nó sẽ được mở rộng như

%~0   - mYbAtCh
%~n0  - mybatch
%~nx0 - mybatch.bat

Nhưng có một ngoại lệ, việc mở rộng trong chương trình con có thể thất bại

echo main- %~0
call :myFunction
exit /b

:myFunction
echo func - %~0
echo func - %~n0
exit /b

Kết quả này để

main - myBatch
Func - :myFunction
func - mybatch

Trong một hàm %~0mở rộng luôn thành tên của hàm, không phải của tệp bó.
Nhưng nếu bạn sử dụng ít nhất một công cụ sửa đổi, nó sẽ hiển thị lại tên tệp!

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.