Ітерація всіх файлів у каталозі за допомогою циклу 'for'


352

Як я можу повторювати кожен файл у каталозі за допомогою forциклу?

І як я міг зрозуміти, чи певний запис - це каталог чи це лише файл?


1
якщо припустити, що ви мали на увазі оболонку Windows за замовчуванням, я переназначив вашу публікацію для дещо більшої ясності
Девід Шмітт,

2
Будь ласка, вкажіть, яку версію Windows ви використовуєте.
джойп

1
Це слід розділити на два окремих питання, оскільки вони незалежні один від одного.
julealgon

Відповіді:


492

У цьому списку перераховані всі файли (та лише файли) у поточному каталозі:

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

Також якщо ви запускаєте цю команду в пакетному файлі, вам потрібно подвоїти знаки%.

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

(спасибі @agnul)


73
Якщо ви не хочете використовувати це рекурсивно, обов'язково вийміть / r
jocull

28
Якщо ви хотіли б повторити тільки імена файлів (не повний шлях) з їх розширеннями в поточній директорії (рекурсивно), ви можете зробити це в такий спосіб : for /r %i in (*) do ( echo %~nxi ). Цей потік теж може бути дуже корисним: stackoverflow.com/questions/112055/… .
Sk8erPeter

2
@Vaccano так, після Do, використовуйте дужки. Тобто так (відлуння% i & del% i). Ви також можете використовувати "enter" замість "&" для декількох команд.
Джей

2
Якщо ви використовуєте команди, як скопіювати / перемістити, а не відлуння, переконайтесь, що ви цитуєте шлях правильно. для / r %% i in (*) do echo "%% i"
Soundararajan

2
Вам, мабуть, потрібно використовувати назви змінних з однієї літери.
Альваро Гонсалес

214

Ітерація через ...

  • ... файли в поточному режимі: for %f in (.\*) do @echo %f
  • ... підкаталоги в поточному режимі: for /D %s in (.\*) do @echo %s
  • ... файли в поточному та всіх підкаталогах: for /R %f in (.\*) do @echo %f
  • ... підкаталоги в поточному та в усіх підкаталогах: for /R /D %s in (.\*) do @echo %s

На жаль, я не знайшов жодного способу ітерації файлів та підкаталів одночасно.

Просто використовуйте cygwin з його bash для набагато більшої функціональності.

Крім цього: Ви помітили, що довідка про вбудову MS Windows - це чудовий ресурс для опису синтаксису командного рядка cmd?

Подивіться також тут: http://technet.microsoft.com/en-us/library/bb490890.aspx


21
%fileі %subdirможе бути тільки один персонаж довго, тобто %f, %s.
Фелікс Домбек

1
"Підкаталоги в поточному режимі" не працюють. Я отримую помилку: s був несподіваним в цей час
Migrate2Lazarus дивіться мій профіль

78

Для повторення кожного файлу працюватиме цикл for:

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

У моєму випадку я також хотів вміст файлу, ім’я та ін.

Це призвело до кількох проблем, і я подумав, що мій випадок використання може допомогти. Ось цикл, який читає інформацію з кожного файлу '.txt' у каталозі і дозволяє вам щось робити з ним (наприклад, setx).

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

* Обмеження: val <= %% f отримає лише перший рядок файлу.


18
Ах, багаторядковий приклад. Дякую за це!
Nyerguds

@Aaron Votre Як закінчити цикл?
nijogeorgep

@nijogeorgep Вам не доведеться "закінчувати" цикл. У моєму прикладі все, що знаходиться в круглих дужках (ехо тощо), буде запущено один раз для кожного файлу '* .txt' у каталозі. Я думаю, що відповідь, яку ви шукаєте, може бути краще пояснена тут: stackoverflow.com/questions/1355791/…
Аарон Вотре

@Aaron Votre Я намагався запустити кілька команд Maven за допомогою скрипту, але він працював як нескінченний цикл, тому я попросив його. Придбати зараз Я додав вихід до свого циклу та виправив свою проблему
nijogeorgep

@nijogeorgep Радий, що ви зрозуміли це!
Аарон Вотре

57

Існує тонка різниця між запуском FORз командного рядка та пакетним файлом. У пакетному файлі потрібно поставити два %символи перед кожною посиланням змінної.

З командного рядка:

FOR %i IN (*) DO ECHO %i

З пакетного файлу:

FOR %%i IN (*) DO ECHO %%i

44

Цей цикл for-циклу перелічить усі файли в каталозі.

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

"delims =" корисно показувати довгі імена файлів з пробілами в ньому ....

'/ b "показувати лише імена, а не дати розміру тощо.

Деякі речі, які потрібно знати про dir's / аргумент.

  • Будь-яке використання "/ a" перераховує все, включаючи приховані та системні атрибути.
  • "/ ad" відображатиме лише підкаталоги, включаючи приховані та системні.
  • Аргумент "/ ad" виключає вміст за допомогою атрибута "D'irectory".
  • "/ adhs" покаже все, але записи з атрибутом "D'irectory", "H'idden" S'ystem.

Якщо ви використовуєте це в командному рядку, видаліть "%".

Сподіваюсь, це допомагає.


10

% 1 відноситься до першого переданого аргументу і не може бути використаний в ітераторі.

Спробуйте це:

@echo off
for %%i in (*.*) do echo %%i

Ти правий. Я спробував у негайному режимі перевірити синтаксис FOR і вставив рядок прямо у відповідь, забувши про параметри :-)
Axeman,


4

Щоб повторити всі файли та папки, які ви можете використовувати

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

Щоб переглядати всі папки не лише з файлами, ви можете використовувати

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

Де /sвсі результати даватимуться по всьому дереву каталогів необмежену глибину. Ви можете пропустити, /sякщо хочете повторити вміст цієї папки, а не їх підпапку

Здійснення пошуку в ітерації

Для повторення певних названих файлів і папок ви можете шукати ім'я та ітерацію, використовуючи для циклу

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

Для повторення певних названих папок / каталогів, а не файлів , використовуйте /ADту саму команду

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

4

У мене виникли проблеми з отриманням відповіді jop для роботи з абсолютним шляхом, поки я не знайшов цю посилання: https://ss64.com/nt/for_r.html

Наступний приклад проходить крізь усі файли в каталозі, заданому абсолютним шляхом.

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

3

У наведеному нижче коді створюється файл із назвою "AllFilesInCurrentDirectorylist.txt" у поточній Директорії, який містить список усіх файлів (лише файлів) у поточному Каталозі. Перевір

dir /b /a-d > AllFilesInCurrentDirectorylist.txt

3

Він також може використовувати команду forfiles :

forfiles /s 

а також перевірити, чи це каталог

forfiles /p c:\ /s /m *.* /c "cmd /c if @isdir==true echo @file is a directory"

@isdir==trueпотрібно бути@isdir==TRUE
psyklopz

2

Я б використовував vbscript (Windows Scripting Host), тому що в пакеті я впевнений, що ви не можете сказати, що ім'я - це файл чи каталог.

У vbs це може бути щось подібне:

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

Перевірте FileSystemObject на MSDN .


Я б використав perl для цього. На жаль, це не до мене.
Vhaerun

Якийсь старий додаток? Сумні речі.
Бірі

Розробник ідіотів бачив пакетні файли і думав, що вони є ліком для всіх наших проблем.
Vhaerun

1
@Vhaerun Однією з переваг Windows Script Host (WSH) над Perl є те, що WSH поставляється заздалегідь з усіма версіями Windows, тоді як Perl потрібно буде встановлювати окремо, що може бути, а може і не бути можливим варіантом у всіх випадках.
Parampreet Dhatt

2

Я використовую команду xcopy з опцією / L для отримання назв файлів. Тож якщо ви хочете отримати або каталог, або всі файли у підкаталозі, ви можете зробити щось подібне:

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

Я просто використовую c: \ в якості місця призначення, оскільки він завжди існує в системах Windows, і він не копіює, тому це не має значення. якщо ви хочете, щоб підкаталоги теж просто скористалися опцією / s. Ви також можете використовувати інші комутатори xcopy, якщо вони потрібні з інших причин.


2

Спробуйте це перевірити, чи файл - це каталог:

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

Це лише скаже вам, чи файл НЕ є каталогом, що також буде правдою, якщо файл не існує, тому обов'язково перевірте це, якщо потрібно. Carets (^) використовується для виходу із символів переспрямування, а вихідний файл файлів переспрямовується на NUL, щоб запобігти його відображенню, тоді як вихід помилки списку DIR переспрямовується на вихід, щоб ви могли протестувати проти повідомлення DIR "Файл не знайдено ".


2

спробуйте це:

::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

він рахує файли .msi та .exe у вашому каталозі (та в підкаталозі). Таким чином, це також робить різницю між папками та файлами як виконуваними файлами.

Просто додайте розширення (.pptx .docx ..), якщо вам потрібно відфільтрувати інші файли в циклі


1

У моєму випадку мені довелося видалити всі файли та папки під тимчасовою папкою. Ось так я закінчила це робити. Мені довелося запустити дві петлі: одна для файлу та одна для папок. Якщо у файлах чи папках є пробіли в їх іменах, тоді вам доведеться використовувати ""

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"
)

1

Ось моя поїздка з коментарями в коді.

Я просто зачісую навички бітча, тому пробачте всі кричущі помилки.

Я спробував написати все в одне рішення якнайкраще, можу з невеликою модифікацією, де цього вимагає користувач.

Деякі важливі зауваження. Просто змініть змінну recursiveна, FALSEякщо ви хочете обробляти лише файли та папки кореневих каталогів. В іншому випадку він проходить через усі папки та файли.

C & C вітаємо ...

@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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.