CMD: *. * Hoặc chỉ *?


47

Quay trở lại những năm 1990, tôi sẽ sử dụng " *.*" để thể hiện bất kỳ tên tệp nào trong MS-DOS, nhưng tôi đã thấy nhiều tập lệnh hơn chỉ sử dụng " *" những ngày này. Nó thực sự làm cho bất kỳ sự khác biệt mà tôi sử dụng?


9
Mặc dù đúng **.*hiện tại tương đương với cmdcác lệnh nội bộ và các tiện ích dòng lệnh hiện đại, một số tiện ích cũ có tham số mặt nạ tệp có thể sử dụng các chức năng khớp tệp cũ hơn và đối với chúng, mặt nạ sẽ không tương đương.
AFH

@AFH Tôi không nghĩ rằng các mã thông báo bằng nhau. Mã *.*thông báo không nên trả lại các tệp không có phần mở rộng.
tuskiomi

1
@tuskiomi - Tôi đồng ý với bạn rằng *.* không nên trả lại các tập tin mở rộng. Thật không may, nó không. Xem câu trả lời của Grawity.
AFH

Câu trả lời:


65

Tên tệp và phần mở rộng đã là một trường duy nhất kể từ khi Windows 95 và NT 3.5 giới thiệu hỗ trợ "tên tệp dài" và các kết hợp ký tự đại diện được thực hiện đối với toàn bộ tên tệp cùng một lúc. Kết quả là, bạn có thể có một tên tệp không có dấu chấm trong đó (có lẽ hiếm đối với các tệp, nhưng rất phổ biến đối với các thư mục / thư mục) và thoạt nhìn *.*sẽ không thực sự khớp với các tệp đó.

Các tập lệnh cũ sử dụng *.* sẽ vẫn hoạt động do mã tương thích - nếu ký tự đại diện kết thúc .*, phần đó bị HĐH bỏ qua. (Vì vậy, nếu bạn muốn khớp cụ thể các tệp với tiện ích mở rộng, tôi đoán bạn sẽ cần *.?*điều đó.)

Nhưng đó không phải là thứ bạn nên dựa vào; nếu bạn đang viết tập lệnh cho các phiên bản Windows hiện đại, hãy tuân theo các quy ước của chúng, không phải các quy ước MS-DOS. (Lưu ý rằng kể từ Windows NT, các tập lệnh .bat không được giải thích bởi MS-DOS nữa mà là bởi cmd.exemột chương trình Win32 gốc.)


Trên Linux và khác nhau Unixen khác, tên & mở rộng chưa bao giờ được tách biệt ở nơi đầu tiên, và có không phải là bất kỳ ma thuật đặc biệt để làm cho *.*công việc, vì vậy *là sự lựa chọn duy nhất mà làm cho tinh thần.


14
"Hãy làm cho việc lọc các tệp có phần mở rộng trở nên khó khăn hơn! Yay!" -Anonymous Microsoft Developer
John Hamilton

50
"Hãy phá vỡ hàng triệu tập lệnh hiện có cho mọi người! Yay!" -Không Nhà phát triển Microsoft, Bao giờ
grawity

3
ISTR rằng trên một số phiên bản cũ của DOS, *sẽ chỉ khớp với tên tệp mà không có phần mở rộng. Cách 'an toàn' để tương thích với cả hai là sử dụng **.
Random832

8
OP nói về Windows, nhưng vì bạn đã đề cập đến Linux: Trong một số shell (ví dụ Bash), *không ( theo mặc định ) không khớp với tên tệp ẩn (bắt đầu bằng a .).
Florian Brucker

4
Đối với một số giá trị của "cấp độ hệ điều hành" ... Đây thực sự là một khái niệm shell (Explorer) trong Windows - kernel không quan tâm đến .exe trên các tệp thực thi, cũng không phải bất cứ thứ gì khác. Liệu Windows Explorer có nhiều "cấp độ hệ điều hành" hơn hay không, ví dụ Nautilus trong Linux có thể được tranh luận hay không.
grawity

11

Đây có thể là đáng nhắc đến rằng unixy / vỏ posixy như vỏ bourne, bash, ksh, zsh, vv làm mở rộng ký tự đại diện (ký tự glob thích *, ?, [range], [!range]và mở rộng khác như niềng răng và những đống mở rộng) để biên dịch một danh sách các đối số trước khi lệnh được thực thi. Vì vậy, việc mở rộng này được thực hiện bởi shell chứ không phải lệnh mà chúng có thể là đối số.

tức là cái vỏ chịu trách nhiệm cho cái gì *, *.*mở rộng ra

 $ ls
 file.csv  file.doc  file.pdf  file.txt  file.xlsx  zz-file-without-extension

 $ (set -xv; foo *)   # is actually expanded to the following
   + foo file.csv file.doc file.pdf file.txt file.xlsx zz-file-without-extension

 $ (set -xv; foo *.*)  # note this does not match `zz-file-without-extension`
   + foo file.csv file.doc file.pdf file.txt file.xlsx

Đây không phải là trường hợp trong CMD (và tương tự đối với các tiện ích powershell ) vì nó chuyển các ký tự toàn cầu nguyên văn sang lệnh được thực thi - và vì vậy việc mở rộng là trách nhiệm của lệnh / tiện ích chứ không phải shell. Vì vậy, cuối cùng, những gì *.*hoặc *phương tiện còn lại cho tiện ích khiến nó tuân thủ (hoặc không) theo các quy ước - đó là lý do tại sao các tiện ích của CMD dir *.*cũng khớp với các tệp (được cho là không chính xác nhưng vẫn bảo tồn các tệp mà không có phần mở rộng.

Tôi tin rằng nó an toàn để tóm tắt theo cách này.

  • Theo CMD nó phụ thuộc vào tiện ích.
  • Trong PowerShell, các tiện ích sử dụng Lớp WildCardPotype sẽ cung cấp một tập hợp con nhất quán các hành vi tích cực.

Một điểm khác biệt nữa là trong CMD, hầu hết các chương trình thực sự chuyển ký tự đại diện thô sang kernel (FindFirstFile), trong khi global trên Linux chỉ lấy danh sách đầy đủ và lọc trong không gian người dùng.
grawity

Khi bạn chạy * trên một thư mục có một triệu tệp, lệnh sẽ khiếu nại quá nhiều tham số. Trong trường hợp xấu nhất, nó có thể âm thầm thả đuôi danh sách. Trong những trường hợp đó, bạn cần đặt hai hoặc nhiều lệnh hoặc lưu danh sách tên tệp trong một tệp để quá trình khác có thể đọc danh sách.
Hải quân Enric

3
@grawity Để chính xác hơn, việc lọc được thực hiện bởi trình điều khiển hệ thống tệp trên Windows. Điều này đặc biệt hữu ích trên các hệ thống tệp mạng (đặc biệt là khi bạn có thể chạy dòng 8 kb đến hệ thống tệp từ xa), nhưng điều đó cũng có nghĩa là bạn không thể thực hiện các tìm kiếm tùy ý cũng như các tìm kiếm được hỗ trợ rõ ràng. Ý nghĩa của việc này đã được khám phá nhiều lần trên blog của Raymond Chen. FindFirstFilebản thân nó là chế độ người dùng (cả kernel32.dll và ntdll.dll đều là thư viện chế độ người dùng - nó là một phần của hệ thống con Win32, không phải kernel), nhưng nó không thực sự làm được gì nhiều.
Luaan

À, tôi có ấn tượng rằng FindFirstFile trực tiếp bao bọc một tòa nhà có tên tương tự (giống như cách mở (3) trong libc chỉ bao bọc mở (2) trong nhân Linux).
grawity

1
@cup: Chỉ cần sử dụng dấu ngoặc kép để ngăn vỏ mở rộng các khối, vì vậy bạn có thể chuyển chúng cho các lệnh. ví dụ mmv "fred.*" "tom.#1". (Việc thay thế sử dụng #1thay vì *, có lợi thế là cho phép bạn đặt lại các trường). mmvkhông được cài đặt theo mặc định trên hầu hết các hệ thống, nhưng các công cụ đổi tên hàng loạt khác thường là. Xem bài viết này về nóstackoverflow.com/questions/417916/how-to-do-a-mass-rename .
Peter Cordes
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.