В Windows пакетный файл с рекурсивным циклом for и именем файла, включая пробелы

9

У меня есть дерево папок, вот так (это только пример, оно будет глубже в моем реальном случае):

C:\test
|   
+---folder1
|       foo bar.txt
|       foobar.txt
|       
+---folder2
|       foo bar.txt
|       foobar.txt
|       
\---folder3
        foo bar.txt
        foobar.txt

В моих файлах есть один или несколько пробелов в имени, и мне нужно выполнить команду над ними, поэтому меня интересует foo bar.txt, но не foobar.txt.

Я попробовал (внутри командного файла):

for /r test %%f in (foo bar.txt) do if exist %%f echo %%f

где команда простая echo.
Это не работает, потому что пространство пропущено, и я не получаю вывод.

Это работает, но это не то, что мне нужно:

for /r test %%f in (foobar.txt) do if exist %%f echo %%f

Это печатает:

C:\test\folder1\foobar.txt
C:\test\folder2\foobar.txt
C:\test\folder3\foobar.txt

Я пытался использовать кавычку ("), но это не работает:

for /r test %%f in ("foo bar.txt") do if exist %%f echo %%f

Это не работает, потому что кавычка все еще включена в вывод:

C:\test\folder1\"foo bar.txt"
C:\test\folder2\"foo bar.txt"
C:\test\folder3\"foo bar.txt"
Алессандро Якопсон
источник

Ответы:

9

Как насчет этого?

for /f "tokens=* delims=" %%a in ('dir "c:\test\foo bar.txt" /s /b') do (
echo %%a
)
Крейг Н
источник
хорошая идея перенести рекурсию в реж! Спасибо.
Алессандро Якопсон
2

Без рекурсивного переключателя вы можете запретить FORвывод кавычек:

for %%f in ("foo bar.txt") do @if exist %%f echo %~dpnxf

Вы могли бы быть в состоянии сделать вложенные FORутверждения. Внешний будет идти по дереву каталогов, а внутренний будет выше.

Приостановлено до дальнейшего уведомления.
источник
Здравствуйте, спасибо за ваш ответ. Я отредактировал вопрос, дерево может быть глубже, чем только один уровень, и поэтому мне нужна рекурсивная форма для.
Алессандро Якопсон
2
@uvts_cvs: FOR /R %%d in (.) DO for %%f ...рекурсивно, но есть некоторые вещи, которые нужно решить, чтобы заставить его работать. Возможно, вам придется использовать отложенное расширение, например. SETLOCAL ENABLEDELAYEDEXPANSIONи !varname!т. д.
приостановлено до дальнейшего уведомления.
% ~ dpnf пропустит расширение файла.
дольмен
@dolmen: исправлена ​​опечатка.
Приостановлено до дальнейшего уведомления.
2

Возможно, вы захотите посмотреть на команду forfiles.

forfiles /S /M "* *" /C "cmd /C echo @PATH"

'/ S' - рекурсия. Поиск по всем подкаталогам

'/ M "* *"' - Маска файла. Ищите только файлы с пробелом в имени.

'/ C "cmd / C echo @PATH"' - Команда. Выполните эту команду для всех найденных файлов.

Пример вывода:

"C:\test\folder1\foo bar.txt"
"C:\test\folder2\foo bar.txt"
"C:\test\folder3\foo bar.txt"
ревун
источник
0

Флаг, fкоторый вам нужен, чтобы получить абсолютное имя файла без кавычек (так что вы можете поместить кавычки, если вам нужно). Но так как он конфликтует с выбранным вами именем переменной, вы должны использовать другое:

for /r test %%i in ("foo bar.txt") do echo %%~fi
дольмен
источник
Это совершенно неверно. Нет конфликта имен переменных и кавычки выводятся командой, которую вы показываете.
Приостановлено до дальнейшего уведомления.
0

Спасибо, Деннис! Я тоже работал над почти идентичной проблемой. Я хотел файл bat, который я мог бы передать во входном параметре в качестве строки поиска имен файлов - рекурсивно по каталогам. На всякий случай это кому-то еще пригодится, вот оно.

::+++++++++
@echo off
setlocal ENABLEDELAYEDEXPANSION
for /R %%d in (.) do (
   for /f "usebackq" %%i in (`dir /b %%d ^| findstr /i %1`) do (
      echo Processing %%i
   )
)
endlocal
skippyV
источник