Bagaimana cara mengekstrak daftar lengkap tipe ekstensi dalam direktori?

28

Dalam suatu direktori, dan secara rekursif dalam sub-direktorinya, artinya setiap direktori dalam suatu direktori diproses, bagaimana cara saya menyusun daftar lengkap ekstensi unik dalam direktori?

OS adalah Windows XP dengan semua pembaruan saat ini, tetapi saya dapat menjalankan skrip jika saya dapat mengetahui apa yang dilakukannya, meskipun saya lebih suka tidak harus menginstal dot-net, karena saya benar-benar tidak menyukainya.

kesalahan besar
sumber

Jawaban:

29

Script batch ini akan melakukannya.

@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

Simpan sebagai .batfile apa pun , dan jalankan dengan perintah batchfile(ganti apa pun yang Anda beri nama) untuk mendaftar direktori saat ini, atau tentukan path dengan batchfile "path". Ini akan mencari semua subdirektori.

Jika Anda ingin mengekspor ke file, gunakan batchfile >filename.txt(atau batchfile "path" >filename.txt).

Penjelasan

Semuanya sebelum for /f...baris hanya mengatur segalanya: ia mendapatkan direktori target untuk dicari, memungkinkan ekspansi tertunda yang memungkinkan saya melakukan pembaruan variabel dalam loop dan mendefinisikan baris baru ( LF) yang dapat saya gunakan untuk output yang lebih rapi. Oh, dan %~1sarana "dapatkan argumen pertama, hapus tanda kutip" yang mencegah tanda kutip dua kali lipat - lihat for /?.

Loop menggunakan dir /b /s /a:-d "%target%"perintah itu, mengambil daftar semua file di semua subdirektori di bawah target.

%%~ximengekstrak ekstensi dari jalur lengkap yang dirdikembalikan oleh perintah.

Ekstensi kosong diganti dengan "FileWithNoExtension", jadi Anda tahu ada file seperti itu - jika saya menambahkan baris kosong sebagai gantinya, itu tidak begitu jelas.

Seluruh daftar saat ini jika dikirim melalui findperintah, untuk memastikan keunikan. Keluaran teks dari perintah find dikirim ke nul, pada dasarnya black hole - kami tidak menginginkannya. Karena kami selalu menambahkan a :di akhir daftar, kami juga harus memastikan kueri penelusuran berakhir dengan :sehingga tidak cocok dengan hasil sebagian - lihat komentar.

% ERRORLEVEL% diatur oleh findperintah, nilai 0 menunjukkan ada kecocokan. Jadi, jika bukan 0, ekstensi saat ini tidak ada dalam daftar sejauh ini dan harus ditambahkan.

Garis gema pada dasarnya output, dan saya juga mengganti placeholder saya ( :) dengan baris baru agar terlihat bagus.

Bob
sumber
+1 @ Bob: Jawaban yang luar biasa, menambahkan penjelasan juga sangat membantu. Baru saja menguji skrip, meninjau hasil tes, dan semuanya bekerja dengan baik. Sekali lagi terima kasih!
kesalahan
1
Itu bekerja dengan sempurna! Saya menggunakan sintaks berikut:batchfile "path" >filename.txt
lucaferrario
Naskah yang bagus! Tetapi ada bug kecil dengan itu: jika folder berisi file aaa.cssdan zzz.cs, ekstensi .cstidak akan dilaporkan oleh skrip.
Goozak
1
@Goozak Whoops. Diperbaiki sekarang Keajaiban pencarian teks ... harus memastikan permintaan pencarian diakhiri dengan :memaksanya agar sesuai dengan batas.
Bob
19

Meskipun tidak sepenuhnya memenuhi persyaratan untuk skrip batch, saya telah menggunakan skrip powershell baris tunggal:

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

Anda berpotensi menjalankannya dari file baris perintah / batch:

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

Saya tidak mengklaim kredit untuk itu, dan tentu saja, Anda perlu Powershell diinstal. Untuk versi Windows yang lebih baru, tidak ada jalan keluarnya.

Jika Anda menghapusnya C:\MyDirectoryakan mengeksekusi di direktori saat ini.

Pada akhirnya akan menghasilkan FileExtensions.txt yang berisi sesuatu seperti berikut:

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

Bergantung pada struktur folder Anda, kadang-kadang Anda mendapatkan kesalahan yang memberi tahu Anda bahwa Anda memiliki jalan panjang.

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.

Setiap subdirektori di sana juga tidak akan diuraikan tetapi hasil untuk yang lainnya masih akan ditampilkan.

Dan Atkinson
sumber
Terima kasih, setuju bahwa ini adalah jawaban yang berguna. Pada catatan yang tidak terkait, agak bingung bagaimana Anda hanya memposting satu jawaban, namun memiliki lencana "Fanatic" untuk mengunjungi Superuser selama 100 hari berturut-turut. Apakah Anda memiliki situs yang ditandai atau sesuatu?
kesalahan
Lencana diberikan pada 2010 ketika saya secara efektif mengintai, tapi saya jauh lebih aktif di SO: stackoverflow.com/users/31532/dan-atkinson . :)
Dan Atkinson
4

Berikut jawaban terperinci menggunakan PowerShell (dengan Windows XP Anda harus menginstal PowerShell):

Hai, Penulis Naskah! Bagaimana Saya Dapat Menggunakan Windows PowerShell untuk Memilih Ekstensi File Unik yang Digunakan dalam Kumpulan File?

RichardM
sumber
1
Sementara PowerShell jelas jauh lebih mudah daripada baris perintah, itu didasarkan pada .NET. Yang, sayangnya, bertentangan dengan "Saya lebih suka tidak harus menginstal dot-net".
Bob
1
+1 @RichardM: Setuju dengan Bob. Juga, kode yang terkait dengan penghitungan instance ekstensi yang ditemukan - tidak mengetahui apa pun tentang PowerShell - tampak sangat berat memori; artinya, alih-alih hanya menjaga hitungan setiap contoh, saya percaya membuat array untuk menyimpan contoh duplikat dari ekstensi untuk setiap ekstensi, kemudian melakukan hitungan untuk setiap array ekstensi di akhir, yang bagi saya sepertinya cara yang sangat aneh. menghitung instance ekstensi. Apakah saya melewatkan sesuatu? (Konon, PowerShell one-liner pertama itu bagus, dan saya akan mencobanya jika saya tidak suka dotnet.)
kesalahan
1
Itu adil. Pertanyaan ini dapat menarik pencari yang lebih terbuka untuk solusi PowerShell. Ingat, pencarian Google yang layak akan menemukan tautan di atas juga.
RichardM
3
+1 untuk tautan ini. kesalahan jelas tidak menyukai segalanya .net, tetapi itu tidak berarti bahwa solusi di atas adalah solusi jangka panjang terbaik untuk masalah ini. Semakin banyak bahasa, semakin baik menurut saya.
Steve Rathbone
1
Berikut ini tautan lain yang membahas pencarian rekursif, menggunakan PowerShell. robertbigec.wordpress.com/2011/01/07/...
goodeye
0

Untuk membuat daftar semua ekstensi unik dari cmd di bawah jalur yang digunakan saat Anda:

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

Saya merasa berguna untuk berubah

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

untuk

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

dan untuk berubah

echo %extlist::=!LF!%

untuk

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

File yang dihasilkan berisi (tidak ada umpan baris, tapi tidak masalah) .bat.pdf.skp.ai.png.jpg.tif.pcp.txt.lst.ttf.dfont.psd.indd.docx.PDF.JPG.gif.jpeg .dwg.exr.FileWithNoExtension.vrlmap.sat.bak.ctb

yang kemudian dapat saya gunakan untuk proyek saya.

Steev43230
sumber