Làm thế nào để trích xuất một danh sách đầy đủ các loại tiện ích mở rộng trong một thư mục?


28

Trong một thư mục và đệ quy trong các thư mục con của nó, nghĩa là mọi thư mục trong một thư mục đều được xử lý, làm cách nào để tôi biên dịch một danh sách đầy đủ các phần mở rộng duy nhất trong thư mục?

Hệ điều hành là Windows XP với tất cả các bản cập nhật hiện tại, nhưng tôi vẫn chạy được kịch bản nếu tôi có thể biết nó đang làm gì, mặc dù tôi không muốn phải cài đặt dot-net, vì tôi thực sự không thích nó.

Câu trả lời:


29

Tập lệnh này sẽ làm điều đó.

@echo off

set target=%~1
if "%target%"=="" set target=%cd%

setlocal EnableDelayedExpansion

set LF=^


rem Previous two lines deliberately left blank for LF to work.

for /f "tokens=*" %%i in ('dir /b /s /a:-d "%target%"') do (
    set ext=%%~xi
    if "!ext!"=="" set ext=FileWithNoExtension
    echo !extlist! | find "!ext!:" > nul
    if not !ERRORLEVEL! == 0 set extlist=!extlist!!ext!:
)

echo %extlist::=!LF!%

endlocal

Lưu nó dưới dạng bất kỳ .battệp nào và chạy nó bằng lệnh batchfile(thay thế bất cứ thứ gì bạn đặt tên cho nó) để liệt kê thư mục hiện tại hoặc chỉ định đường dẫn bằng batchfile "path". Nó sẽ tìm kiếm tất cả các thư mục con.

Nếu bạn muốn xuất thành tệp, sử dụng batchfile >filename.txt(hoặc batchfile "path" >filename.txt).

Giải trình

Mọi thứ trước khi for /f...dòng chỉ thiết lập mọi thứ: nó lấy thư mục đích để tìm kiếm, cho phép mở rộng bị trì hoãn cho phép tôi thực hiện cập nhật các biến trong vòng lặp và xác định một dòng mới ( LF) mà tôi có thể sử dụng cho đầu ra gọn gàng hơn. Ồ, và %~1có nghĩa là "lấy đối số đầu tiên, xóa dấu ngoặc kép" để ngăn dấu ngoặc kép tăng lên - xem for /?.

Vòng lặp sử dụng dir /b /s /a:-d "%target%"lệnh đó , lấy một danh sách tất cả các tệp trong tất cả các thư mục con bên dưới mục tiêu.

%%~xitrích xuất phần mở rộng ra khỏi đường dẫn đầy đủ mà dirlệnh trả về.

Một tiện ích mở rộng trống được thay thế bằng "FileWithNoExtension", vì vậy bạn biết có một tệp như vậy - nếu tôi đã thêm một dòng trống thay thế, nó không hoàn toàn rõ ràng.

Toàn bộ danh sách hiện tại nếu được gửi qua một findlệnh, để đảm bảo tính duy nhất. Đầu ra văn bản của lệnh find được gửi tới nul, về cơ bản là một lỗ đen - chúng tôi không muốn nó. Vì chúng tôi luôn nối thêm :vào cuối danh sách, chúng tôi cũng nên đảm bảo truy vấn tìm kiếm kết thúc bằng một :kết quả không khớp với một phần kết quả - xem bình luận.

% ERRORLEVEL% được đặt bởi findlệnh, giá trị 0 cho biết có khớp. Vì vậy, nếu không phải là 0, thì phần mở rộng hiện tại không có trong danh sách và nên được thêm vào.

Dòng echo về cơ bản là đầu ra và tôi cũng thay thế trình giữ chỗ của tôi ( :) bằng các dòng mới để làm cho nó trông đẹp hơn.


+1 @Bob: Câu trả lời tuyệt vời, thêm lời giải thích cũng là một trợ giúp rất lớn. Chỉ cần kiểm tra kịch bản, xem xét kết quả của bài kiểm tra, và mọi thứ đều hoạt động tốt. Một lần nữa cám ơn!
sai lầm ngớ ngẩn

1
Nó hoạt động HOÀN HẢO! Tôi đã sử dụng cú pháp sau:batchfile "path" >filename.txt
lucaferrario

Kịch bản tuyệt vời! Nhưng có một lỗi nhỏ với nó: nếu thư mục chứa tệp aaa.csszzz.cs, phần mở rộng .cssẽ không được tập lệnh báo cáo.
Goozak

1
@Goozak Rất tiếc. Đã sửa bây giờ. Các kỳ quan của tìm kiếm văn bản ... phải đảm bảo truy vấn tìm kiếm kết thúc :để buộc nó phải khớp với các ranh giới.
Bob

19

Mặc dù không đáp ứng nghiêm ngặt yêu cầu đối với tập lệnh bó, tôi đã sử dụng tập lệnh powershell một dòng:

Get-Childitem C:\MyDirectory -Recurse | WHERE { -NOT $_.PSIsContainer } | Group Extension -NoElement | Sort Count -Desc > FileExtensions.txt

Bạn có khả năng có thể chạy nó từ tệp dòng lệnh / bó:

Powershell -Command "& Get-Childitem C:\MyDirectory -Recurse | WHERE { -NOT $_.PSIsContainer } | Group Extension -NoElement | Sort Count -Desc > FileExtensions.txt"

Tôi khẳng định không có tín dụng cho nó, và tất nhiên, bạn sẽ cần cài đặt Powershell. Đối với các phiên bản Windows mới hơn, không có bất kỳ vấn đề nào xảy ra.

Nếu bạn loại bỏ C:\MyDirectorynó sẽ thực thi trong thư mục hiện tại.

Cuối cùng, nó sẽ tạo ra một FileExtensions.txt có chứa một cái gì đó như sau:

+-------+------+
| Count | Name |
+-------+------+
| ----- | ---- |
| 8216  | .xml |
| 4854  | .png |
| 4378  | .dll |
| 3565  | .htm |
| ...   | ...  |
+-------+------+

Tùy thuộc vào cấu trúc thư mục của bạn, đôi khi bạn có thể gặp lỗi thông báo cho bạn rằng bạn có một con đường dài.

Get-ChildItem : The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

Bất kỳ thư mục con nào trong đó cũng sẽ không được phân tích cú pháp nhưng kết quả cho mọi thứ khác vẫn sẽ hiển thị.


Cảm ơn, đồng ý rằng đó là một câu trả lời hữu ích. Trên một ghi chú không liên quan, bit bối rối về cách bạn chỉ đăng một câu trả lời duy nhất, nhưng vẫn có huy hiệu "Fanatic" để truy cập Superuser trong 100 ngày liên tiếp. Bạn có trang web được đánh dấu hoặc một cái gì đó?
sai lầm ngớ ngẩn

Các huy hiệu đã được trao vào năm 2010 khi tôi có hiệu quả lẩn quất, nhưng tôi xa tích cực hơn trên SO: stackoverflow.com/users/31532/dan-atkinson . :)
Dan Atkinson

4

1
Mặc dù PowerShell chắc chắn dễ dàng hơn nhiều so với dòng lệnh, nhưng nó dựa trên .NET. Thật không may, đi ngược lại "Tôi không muốn phải cài đặt dot-net".
Bob

1
+1 @RichardM: Đồng ý với Bob. Ngoài ra, mã liên quan đến việc đếm các phiên bản mở rộng được tìm thấy - không biết gì về PowerShell - có vẻ rất nặng bộ nhớ; có nghĩa là thay vì chỉ giữ một số lượng của mỗi phiên bản, tôi tin rằng việc tạo một mảng để lưu trữ các phiên bản trùng lặp của một tiện ích mở rộng cho mỗi tiện ích mở rộng, sau đó thực hiện đếm cho mỗi mảng mở rộng ở cuối, đối với tôi có vẻ như là một cách rất kỳ quặc đếm các trường hợp mở rộng. Tui bỏ lỡ điều gì vậy? (Điều đó nói rằng, người đầu tiên PowerShell one-liner là tốt đẹp, và tôi muốn thử nó nếu tôi không thích DotNet.)
sai lầm

1
Điều đó công bằng. Câu hỏi này có thể thu hút những người tìm kiếm cởi mở hơn với giải pháp PowerShell. Hãy nhớ rằng, một tìm kiếm Google tốt cũng sẽ tìm thấy liên kết ở trên.
RichardM

3
+1 cho liên kết này. sai lầm rõ ràng không thích mọi thứ .net, nhưng điều đó không có nghĩa là giải pháp trên là giải pháp lâu dài tốt nhất cho vấn đề này. Càng nhiều ngôn ngữ tôi càng nghĩ tốt.
Steve Rathbone

1
Đây là một liên kết khác giải quyết tìm kiếm đệ quy, sử dụng powershell. robertbigec.wordpress.com/2011/01/07/ khăn
goodeye

0

Để liệt kê tất cả các tiện ích mở rộng duy nhất từ ​​cmd theo đường dẫn bạn đang sử dụng:

Powershell -Command "Get-ChildItem . -Include *.* -Recurse | Select-Object Extension | Sort-Object -Property Extension -Unique"

0

Tôi thấy nó hữu ích để thay đổi

if "!ext!"=="" set ext=FileWithNoExtension

đến

if "!ext!"=="" set ext=.FileWithNoExtension

và để thay đổi

echo %extlist::=!LF!%

đến

echo %extlist::=!LF!% > ext-list.txt

Tệp được tạo có chứa (không có nguồn cấp dữ liệu, nhưng không có vấn đề) .bat.pdf.skp.ai.png.jpg.tif.pcp.txt.lst.ttf.dfont. .dwg.exr.FileWithNoExtension.vrlmap.sat.bak.ctb

mà sau đó tôi đã có thể sử dụng cho dự án của mình.

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.