W systemie Windows: plik wsadowy z rekurencyjną pętlą for i nazwą pliku zawierającą spacje

9

Mam drzewo folderów, takie jak to (to tylko przykład, będzie głębsze w moim prawdziwym przypadku):

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

Moje pliki mają jedną lub więcej spacji w nazwie i muszę wykonać na nich polecenie, więc interesuje mnie foo bar.txt, ale nie foobar.txt.

Próbowałem (w pliku wsadowym):

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

gdzie polecenie jest proste echo.
To nie działa, ponieważ przestrzeń jest pomijana i nie otrzymuję danych wyjściowych.

To działa, ale nie jest to, czego potrzebuję:

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

Drukuje:

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

Próbowałem użyć znaku cudzysłowu („), ale to nie działa:

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

To nie działa, ponieważ znak cudzysłowu jest nadal zawarty w danych wyjściowych:

C:\test\folder1\"foo bar.txt"
C:\test\folder2\"foo bar.txt"
C:\test\folder3\"foo bar.txt"
Alessandro Jacopson
źródło

Odpowiedzi:

9

Co powiesz na to?

for /f "tokens=* delims=" %%a in ('dir "c:\test\foo bar.txt" /s /b') do (
echo %%a
)
Craig H.
źródło
dobry pomysł, aby przenieść rekursję w reż! Dziękuję Ci.
Alessandro Jacopson
2

Bez przełącznika rekurencyjnego możesz powiedzieć, FORaby nie drukować cytatów:

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

Możesz być w stanie wykonać zagnieżdżone FORinstrukcje. Zewnętrzne będzie chodzić po drzewie katalogów, a wewnętrzne będzie tym powyżej.

Wstrzymano do odwołania.
źródło
Witam, dziękuję za odpowiedź. Zredagowałem pytanie, drzewo może być głębsze niż tylko jeden poziom, więc potrzebuję rekurencji.
Alessandro Jacopson,
2
@ uvts_cvs: FOR /R %%d in (.) DO for %%f ...jest rekurencyjny, ale byłoby kilka rzeczy do wypracowania, aby działało. Może być konieczne na przykład użycie opóźnionego rozszerzenia. SETLOCAL ENABLEDELAYEDEXPANSIONi !varname!itp.
Wstrzymane do odwołania.
% ~ dpnf pominie rozszerzenie pliku.
dolmen
@dolmen: Naprawiono literówkę.
Wstrzymano do odwołania.
2

Możesz przyjrzeć się poleceniu forfiles.

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

„/ S” - rekurencja. Przeszukaj wszystkie podkatalogi

'/ M "* *"' - maska ​​pliku. Wyszukaj tylko pliki ze spacją w nazwie.

'/ C "cmd / C echo @PATH"' - Polecenie. Wydaj to polecenie na wszystkich znalezionych plikach.

Przykładowe dane wyjściowe:

"C:\test\folder1\foo bar.txt"
"C:\test\folder2\foo bar.txt"
"C:\test\folder3\foo bar.txt"
Wyjec
źródło
0

Flaga fjest tą, której potrzebujesz, aby uzyskać bezwzględną nazwę pliku bez cudzysłowów (w razie potrzeby możesz wstawiać cudzysłowy). Ale ponieważ jest on sprzeczny z wybraną nazwą zmiennej, musisz użyć innej:

for /r test %%i in ("foo bar.txt") do echo %%~fi
dolmen
źródło
To całkowicie niepoprawne. Nie ma konfliktu nazw zmiennych, a wyświetlane polecenie wypisuje cudzysłowy.
Wstrzymano do odwołania.
0

Dzięki, Dennis! Ja także pracowałem nad prawie identycznym problemem. Chciałem plik nietoperza, który mógłbym przekazać w parmie wejściowej jako ciąg wyszukiwania nazw plików - rekurencyjnie przez katalogi. Na wszelki wypadek jest to przydatne dla kogoś innego.

::+++++++++
@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
źródło