Выполните итерацию всех файлов в каталоге, используя цикл for

353

Как я могу перебрать каждый файл в каталоге, используя forцикл?

И как я могу определить, является ли определенная запись каталогом или просто файлом?

Vhaerun
источник
1
предполагая, что вы имели в виду оболочку Windows по умолчанию, я пометил ваш пост для большей ясности
David Schmitt
2
Пожалуйста, укажите также, какую версию Windows вы используете.
Джоп
1
Это должно быть разделено на два отдельных вопроса, так как они независимы друг от друга.
Jullealgon

Ответы:

493

Здесь перечислены все файлы (и только файлы) в текущем каталоге:

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

Также, если вы запускаете эту команду в пакетном файле, вам нужно удвоить знаки%.

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

(спасибо @agnul)

Джоп
источник
73
Если вы не хотите использовать это рекурсивно, убедитесь, что вы
удалили
28
Если вы хотели бы повторить только имена файлов (не полный путь) с их расширениями в текущей директории (рекурсивно), вы можете сделать это следующим образом : for /r %i in (*) do ( echo %~nxi ). Этот поток может быть действительно полезным: stackoverflow.com/questions/112055/… .
Sk8erPeter
2
@Vaccano да, после Do используйте круглые скобки. То есть (эхо% i & del% i). Вы также можете использовать «ввод» вместо «&» для нескольких команд.
Jay
2
Если вы используете такие команды, как копирование / перемещение, а не эхо, убедитесь, что вы правильно указали путь. for / r %% i in (*) делает эхо "%% 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

Marco
источник
21
%fileи %subdirможет быть только один персонаж долго, то есть %f, %s.
Феликс Домбек
1
«subdirs in current dir» не работает. Я получаю ошибку: 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
Ах, многострочный пример. Спасибо за это!
Нергудс
@ Аарон Вотре Как закончить цикл?
nijogeorgep
@nijogeorgep Вам не нужно «заканчивать» цикл. В моем примере все внутри скобок (echo и т. Д.) Будет запускаться один раз для каждого файла * .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 аргумент.

  • Любое использование «/ a» будет перечислять все, включая скрытые и системные атрибуты.
  • «/ ad» будет показывать только подкаталоги, включая скрытые и системные.
  • Аргумент «/ ad» удаляет содержимое с атрибутом «D».
  • «/ adhs» покажет все, кроме записей с «D'irectory», «H'idden» S'ystem.

Если вы используете это в командной строке, удалите «%».

Надеюсь это поможет.

сойка
источник
10

% 1 ссылается на первый переданный аргумент и не может использоваться в итераторе.

Попробуй это:

@echo off
for %%i in (*.*) do echo %%i
Сэм Мелдрум
источник
Вы правы. Я попытался в немедленном режиме проверить синтаксис FOR и вставил строку прямо в ответ, забыв о параметрах :-)
Axeman
5
for %1 in (*.*) do echo %1

Попробуйте "HELP FOR" в cmd для полного руководства

Это руководство для команд XP. http://www.ss64.com/nt/

лесоруб
источник
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

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
jafarbtech
источник
4

У меня были проблемы с получением ответа jop для работы с абсолютным путем, пока я не нашел эту ссылку: https://ss64.com/nt/for_r.html

В следующем примере циклически перебираются все файлы в каталоге, заданном абсолютным путем.

For /R C:\absoulte\path\ %%G IN (*.*) do (
  Echo %%G
)
datchung
источник
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 .

Biri
источник
Я бы использовал Perl для этого. К сожалению, это не мое дело.
Ваэрун
Какое-то старое приложение? Грустные вещи
Бири
Разработчик-идиот увидел пакетные файлы и подумал, что они являются лекарством от всех наших проблем.
Ваэрун
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, если они вам нужны по другим причинам.

Knoots
источник
2

Попробуйте это, чтобы проверить, является ли файл каталогом:

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

Это только скажет вам, является ли файл НЕ каталогом, что также будет истинно, если файл не существует, поэтому обязательно проверьте это сначала, если вам нужно. Символы вставки (^) используются для экранирования символов перенаправления, и вывод списка файлов перенаправляется в NUL, чтобы предотвратить его отображение, а вывод ошибок списка DIR перенаправляется на вывод, чтобы можно было проверить сообщение DIR «Файл не найден» ».

sugerfunk
источник
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
Ste
источник