Iterasi semua file dalam direktori menggunakan loop 'untuk'

353

Bagaimana saya bisa mengulangi setiap file dalam direktori menggunakan forloop?

Dan bagaimana saya bisa tahu apakah entri tertentu adalah direktori atau apakah itu hanya sebuah file?

Vhaerun
sumber
1
dengan asumsi Anda maksud shell windows default, saya telah retagged posting Anda untuk sedikit lebih jelas
David Schmitt
2
Harap tentukan juga versi Windows apa yang Anda gunakan.
Lompat
1
Ini harus dibagi menjadi dua pertanyaan terpisah karena mereka independen satu sama lain.
julealgon

Jawaban:

493

Ini mencantumkan semua file (dan hanya file) di direktori saat ini:

for /r %i in (*) do echo %i

Juga jika Anda menjalankan perintah itu dalam file batch Anda harus menggandakan tanda%.

for /r %%i in (*) do echo %%i

(terima kasih @agnul)

pel
sumber
73
Jika Anda tidak ingin menggunakan ini secara rekursif, pastikan Anda mengeluarkan / r
jocull
28
Jika Anda ingin echo hanya nama file (tidak path lengkap) dengan ekstensi mereka di direktori saat ini (rekursif), Anda dapat melakukannya seperti ini: for /r %i in (*) do ( echo %~nxi ). Utas ini juga bisa sangat berguna: stackoverflow.com/questions/112055/… .
Sk8erPeter
2
@Accano ya, setelah Do, gunakan tanda kurung. Yaitu (echo% i & del% i). Anda juga dapat menggunakan "enter" daripada "&" untuk beberapa perintah.
Jay
2
Jika Anda menggunakan perintah seperti salin / pindah daripada gema, pastikan Anda mengutip path dengan benar. untuk / r %% i di (*) do echo "%% i"
Soundararajan
2
Anda tampaknya perlu menggunakan nama variabel satu huruf.
Álvaro González
214

Iterate melalui ...

  • ... file dalam direktori saat ini: for %f in (.\*) do @echo %f
  • ... subdirektori dalam direktori saat ini: for /D %s in (.\*) do @echo %s
  • ... file saat ini dan semua subdirs: for /R %f in (.\*) do @echo %f
  • ... subdir dalam arus dan semua subdir: for /R /D %s in (.\*) do @echo %s

Sayangnya saya tidak menemukan cara untuk beralih dari file dan subdirer pada saat yang sama.

Cukup gunakan cygwin dengan bash-nya untuk lebih banyak fungsionalitas.

Terlepas dari ini: Apakah Anda memperhatikan, bahwa bantuan buildin dari MS Windows adalah sumber yang bagus untuk deskripsi sintaks baris perintah cmd?

Lihat juga di sini: http://technet.microsoft.com/en-us/library/bb490890.aspx

Marco
sumber
21
%filedan %subdirhanya dapat satu karakter yang panjang, yaitu %f, %s.
Felix Dombek
1
'subdir di direktori saat ini' tidak berfungsi. Saya mendapatkan kesalahan: s tidak terduga pada saat ini
Migrate2Lazarus melihat profil saya
78

Untuk beralih ke setiap file a for loop akan berfungsi:

for %%f in (directory\path\*) do ( something_here )

Dalam kasus saya, saya juga menginginkan konten file, nama, dll.

Ini mengarah ke beberapa masalah dan saya pikir kasus penggunaan saya mungkin membantu. Berikut ini adalah loop yang membaca info dari setiap file '.txt' di direktori dan memungkinkan Anda melakukan sesuatu dengannya (setx misalnya).

@ECHO OFF
setlocal enabledelayedexpansion
for %%f in (directory\path\*.txt) do (
  set /p val=<%%f
  echo "fullname: %%f"
  echo "name: %%~nf"
  echo "contents: !val!"
)

* Batasan: val <= %% f hanya akan mendapatkan baris pertama dari file.

Aaron Votre
sumber
18
Ah, contoh multi-line. Terima kasih untuk itu!
Nyerguds
@ Aaron Votre Bagaimana cara mengakhiri loop?
nijogeorgep
@nijogeorgep Anda tidak perlu "mengakhiri" perulangan. Dalam contoh saya, semua yang ada di dalam tanda kurung, (gema, dll), akan dijalankan sekali untuk setiap file '* .txt' di direktori. Saya pikir jawaban yang Anda cari mungkin lebih baik dijelaskan di sini: stackoverflow.com/questions/1355791/…
Aaron Votre
@ Aaron Votre Saya mencoba menjalankan beberapa perintah pakar menggunakan skrip, tetapi itu berjalan sebagai infinite loop, Jadi saya memintanya. Beli sekarang saya menambahkan jalan keluar ke loop saya dan memperbaiki masalah saya
nijogeorgep
@nijogeorgep Senang Anda menemukan jawabannya!
Aaron Votre
57

Ada perbedaan halus antara menjalankan FORdari baris perintah dan dari file batch. Dalam file batch, Anda harus meletakkan dua %karakter di depan setiap referensi variabel.

Dari baris perintah:

FOR %i IN (*) DO ECHO %i

Dari file batch:

FOR %%i IN (*) DO ECHO %%i
kata mutiara
sumber
44

Untuk-loop ini akan mencantumkan semua file dalam direktori.

pushd somedir
for /f "delims=" %%f in ('dir /b /a-d-h-s') do echo %%f
popd

"delims =" berguna untuk menampilkan nama file panjang dengan spasi di dalamnya ....

'/ b "hanya tampilkan nama, bukan ukuran tanggal, dll.

Beberapa hal yang perlu diketahui tentang dir / argumen.

  • Setiap penggunaan "/ a" akan mendaftar semuanya, termasuk atribut tersembunyi dan sistem.
  • "/ iklan" hanya akan menampilkan subdirektori, termasuk yang tersembunyi dan sistem.
  • Argumen "/ iklan" menghilangkan konten dengan atribut 'D'directory.
  • "/ adhs" akan menampilkan segalanya, tetapi entri dengan atribut 'D'directory,' H'idden 'S'ystem.

Jika Anda menggunakan ini pada commandline, hapus "%".

Semoga ini membantu.

Jay
sumber
10

% 1 merujuk pada argumen pertama yang diteruskan dan tidak dapat digunakan dalam iterator.

Coba ini:

@echo off
for %%i in (*.*) do echo %%i
Sam Meldrum
sumber
Kamu benar. Saya sudah mencoba dalam mode langsung untuk memeriksa sintaks FOR dan menyisipkan baris langsung ke jawaban yang lupa tentang parameter :-)
Axeman
5
for %1 in (*.*) do echo %1

Coba "BANTUAN" dalam cmd untuk panduan lengkap

Ini adalah panduan untuk perintah XP. http://www.ss64.com/nt/

Axeman
sumber
4

Untuk mengulangi semua file dan folder yang dapat Anda gunakan

for /F "delims=" %%a in ('dir /b /s') do echo %%a

Untuk beralih hanya melalui semua folder tidak dengan file, maka Anda dapat menggunakan

for /F "delims=" %%a in ('dir /a:d /b /s') do echo %%a

Di mana /sakan memberikan semua hasil di seluruh pohon direktori di kedalaman tak terbatas. Anda bisa melewati/s jika Anda ingin mengulangi isi folder itu bukan sub foldernya

Menerapkan pencarian dalam iterasi

Untuk beralih melalui file dan folder bernama tertentu Anda dapat mencari nama dan beralih menggunakan untuk loop

for /F "delims=" %%a in ('dir "file or folder name" /b /s') do echo %%a

Untuk beralih melalui folder / direktori bernama tertentu dan bukan file , kemudian gunakan /ADperintah yang sama

for /F "delims=" %%a in ('dir "folder name" /b /AD /s') do echo %%a
jafarbtech
sumber
4

Saya kesulitan mendapatkan jawaban pel untuk bekerja dengan jalur absolut sampai saya menemukan referensi ini: https://ss64.com/nt/for_r.html

Contoh berikut loop melalui semua file dalam direktori yang diberikan oleh path absolut.

For /R C:\absoulte\path\ %%G IN (*.*) do (
  Echo %%G
)
datchung
sumber
3

Kode berikut membuat file Bernama "AllFilesInCurrentDirectorylist.txt" di Direktori saat ini, yang berisi daftar semua file (Hanya File) di Direktori saat ini. Coba lihat

dir /b /a-d > AllFilesInCurrentDirectorylist.txt
Ankur
sumber
3

Itu juga bisa menggunakan perintah forfiles :

forfiles /s 

dan juga memeriksa apakah itu adalah direktori

forfiles /p c:\ /s /m *.* /c "cmd /c if @isdir==true echo @file is a directory"
Maks
sumber
@isdir==trueperlu@isdir==TRUE
psyklopz
2

Saya akan menggunakan vbscript (Windows Scripting Host), karena dalam batch saya yakin Anda tidak bisa mengatakan bahwa nama adalah file atau direktori.

Dalam vbs, bisa jadi seperti ini:

Dim fileSystemObject
Set fileSystemObject = CreateObject("Scripting.FileSystemObject")

Dim mainFolder
Set mainFolder = fileSystemObject.GetFolder(myFolder)

Dim files
Set files = mainFolder.Files

For Each file in files
...
Next

Dim subFolders
Set subFolders = mainFolder.SubFolders

For Each folder in subFolders
...
Next

Periksa FileSystemObject di MSDN .

Biri
sumber
Saya akan menggunakan perl untuk melakukan ini. Sayangnya, itu tidak terserah saya.
Vhaerun
Beberapa aplikasi lama? Hal yang menyedihkan.
Biri
Pengembang idiot melihat file batch dan berpikir bahwa itu adalah obat untuk semua masalah kita.
Vhaerun
1
@Vhaerun Salah satu keunggulan Windows Script Host (WSH) dibandingkan Perl adalah WSH sudah diinstal sebelumnya dengan semua versi Windows, sedangkan Perl perlu diinstal secara terpisah, yang mungkin atau mungkin bukan opsi yang layak dalam semua kasus.
Parampreet Dhatt
2

Saya menggunakan perintah xcopy dengan opsi / L untuk mendapatkan nama file. Jadi jika Anda ingin mendapatkan direktori atau semua file di subdirektori Anda dapat melakukan sesuatu seperti ini:

for /f "delims=" %%a IN ('xcopy "D:\*.pdf" c:\ /l') do echo %%a

Saya hanya menggunakan c: \ sebagai tujuan karena selalu ada di sistem windows dan tidak menyalin sehingga tidak masalah. jika Anda ingin subdirektori juga cukup gunakan opsi / s pada akhirnya. Anda juga dapat menggunakan sakelar xcopy lain jika Anda membutuhkannya karena alasan lain.

Knoots
sumber
2

Coba ini untuk menguji apakah file adalah direktori:

FOR /F "delims=" %I IN ('DIR /B /AD "filename" 2^>^&1 ^>NUL') DO IF "%I" == "File Not Found" ECHO Not a directory

Ini hanya akan memberi tahu Anda apakah file BUKAN direktori, yang juga akan benar jika file tersebut tidak ada, jadi pastikan untuk memeriksa itu terlebih dahulu jika Anda perlu. Tanda sisipan (^) digunakan untuk menghindari simbol pengalihan dan output daftar file diarahkan ke NUL untuk mencegahnya ditampilkan, sedangkan output kesalahan daftar DIR diarahkan ke output sehingga Anda dapat menguji terhadap pesan DIR "File Tidak Ditemukan ".

sugerfunk
sumber
2

coba ini:

::Example directory
set SetupDir=C:\Users

::Loop in the folder with "/r" to search in recursive folders, %%f being a loop ::variable 
for /r "%SetupDir%" %%f in (*.msi *.exe) do set /a counter+=1

echo there are %counter% files in your folder

itu menghitung file .msi dan .exe di direktori Anda (dan di sub direktori). Jadi itu juga membuat perbedaan antara folder dan file sebagai executable.

Tambahkan saja ekstensi (.pptx .docx ..) jika Anda perlu memfilter file lain dalam loop

Poni kecil
sumber
1

Dalam kasus saya, saya harus menghapus semua file dan folder di bawah folder temp. Jadi begini akhirnya saya melakukannya. Saya harus menjalankan dua loop satu untuk file dan satu untuk folder. Jika file atau folder memiliki ruang dalam namanya, maka Anda harus menggunakan ""

cd %USERPROFILE%\AppData\Local\Temp\
rem files only
for /r %%a in (*) do (
echo deleting file "%%a" ...
if exist "%%a" del /s /q "%%a"
)
rem folders only
for /D %%a in (*) do (
echo deleting folder "%%a" ...
if exist "%%a" rmdir /s /q "%%a"
)
Sam B
sumber
1

Inilah saya pergi dengan komentar dalam kode.

Saya hanya menyikat oleh keterampilan biatch jadi maafkan kesalahan mencolok.

Saya mencoba menulis solusi all in one sebaik mungkin dengan sedikit modifikasi di mana pengguna membutuhkannya.

Beberapa catatan penting: Ubah saja variabelnyarecursive untuk FALSEjika Anda hanya ingin file direktori root dan folder diproses. Kalau tidak, itu akan melewati semua folder dan file.

C&C sangat disambut ...

@echo off
title %~nx0
chcp 65001 >NUL
set "dir=c:\users\%username%\desktop"
::
:: Recursive Loop routine - First Written by Ste on - 2020.01.24 - Rev 1
::
setlocal EnableDelayedExpansion
rem THIS IS A RECURSIVE SOLUTION [ALBEIT IF YOU CHANGE THE RECURSIVE TO FALSE, NO]
rem By removing the /s switch from the first loop if you want to loop through
rem the base folder only.
set recursive=TRUE
if %recursive% equ TRUE ( set recursive=/s ) else ( set recursive= )
endlocal & set recursive=%recursive%
cd /d %dir%
echo Directory %cd%
for %%F in ("*") do (echo    → %%F)                                 %= Loop through the current directory. =%
for /f "delims==" %%D in ('dir "%dir%" /ad /b %recursive%') do (    %= Loop through the sub-directories only if the recursive variable is TRUE. =%
  echo Directory %%D
  echo %recursive% | find "/s" >NUL 2>NUL && (
    pushd %%D
    cd /d %%D
    for /f "delims==" %%F in ('dir "*" /b') do (                      %= Then loop through each pushd' folder and work on the files and folders =%
      echo %%~aF | find /v "d" >NUL 2>NUL && (                        %= This will weed out the directories by checking their attributes for the lack of 'd' with the /v switch therefore you can now work on the files only. =%
      rem You can do stuff to your files here.
      rem Below are some examples of the info you can get by expanding the %%F variable.
      rem Uncomment one at a time to see the results.
      echo    → %%~F           &rem expands %%F removing any surrounding quotes (")
      rem echo    → %%~dF          &rem expands %%F to a drive letter only
      rem echo    → %%~fF          &rem expands %%F to a fully qualified path name
      rem echo    → %%~pF          &rem expands %%A to a path only
      rem echo    → %%~nF          &rem expands %%F to a file name only
      rem echo    → %%~xF          &rem expands %%F to a file extension only
      rem echo    → %%~sF          &rem expanded path contains short names only
      rem echo    → %%~aF          &rem expands %%F to file attributes of file
      rem echo    → %%~tF          &rem expands %%F to date/time of file
      rem echo    → %%~zF          &rem expands %%F to size of file
      rem echo    → %%~dpF         &rem expands %%F to a drive letter and path only
      rem echo    → %%~nxF         &rem expands %%F to a file name and extension only
      rem echo    → %%~fsF         &rem expands %%F to a full path name with short names only
      rem echo    → %%~dp$dir:F    &rem searches the directories listed in the 'dir' environment variable and expands %%F 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
      rem echo    → %%~ftzaF       &rem expands %%F to a DIR like output line
      )
      )
    popd
    )
  )
echo/ & pause & cls
Ste
sumber