Jak sprawdzić, czy katalog istnieje w systemie Windows?

59

Chciałbym przetłumaczyć ten skrypt Linux / Bash na powłokę Windows:

if test -d myDirName; then echo "ok"; else mkdir myDirName; fi

Sprawdza, czy katalog istnieje, a jeśli nie, to go tworzy.

Pietro
źródło
3
Rzeczywista komenda linux / bash byłoby po prostu: mkdir -p myDirName. Po spędzeniu dni na tłumaczeniu stosunkowo prostych skryptów bash na batch-sh * t (przypisywanie wyniku funkcji zmiennej?), Postanowiłem po prostu zmusić ludzi do zainstalowania cygwina.
Michael

Odpowiedzi:

73
@echo off
IF exist myDirName ( echo myDirName exists ) ELSE ( mkdir myDirName && echo myDirName created)

Dodane przez Barlop

Chociaż powyższe działa w tej konkretnej sytuacji, tytuł mówi o testowaniu specjalnie dla katalogu. Komentowanie Phogga jest if exist mydirname\raczej if exist mydirnamesposobem niż sposobem. Niektóre odpowiedzi wykorzystały \ nul, ale \ nul jest problematyczne w NT. Nie uwzględnienie końcowego ukośnika odwrotnego spowoduje sprawdzenie pliku lub katalogu. Tak więc, dla katalogu, dołącz końcowy ukośnik odwrotny.

Sathyajith Bhat
źródło
23
Jest to poprawne w przypadku testowania istnienia pliku, ale skąd wiesz, że jest to katalog? Najprostsza odpowiedź brzmi, if exist mydirname\ a reszta, jak mówisz. Alternatywnie możesz dostać plik testbinarny i używać go w systemie Windows.
phogg
@phogg: W kontekście tego konkretnego pytania: jeśli istnieje, ale jest plikiem, nadal nie możesz mkdir.
grawity
@grawity: Jeśli istnieje, ale jest plikiem, skrypt prawdopodobnie później zawiedzie podczas próby użycia go jako katalogu, co prawdopodobnie nie jest tym, czego chcesz.
phogg
jak mogę sprawdzić, jeśli nie istnieje?
Sungguk Lim,
1
@sunglim, pisząc `` Jeśli nie istnieje mojaDirName \ `podobnie if not 1==1 echo hmm lub jeśli istnieje mojaDirName \ ELSE
blahblahblah
20

Oto, co właśnie odkryłem:

Możesz sprawdzić, czy istnieje plik zerowy; jeśli katalog istnieje, będzie zawierał plik nul, jeśli plik nul nie istnieje, to katalog nie istnieje.

IF exist myDirName/nul ( echo myDirName exists ) ELSE ( mkdir myDirName && echo myDirName created)
dev008
źródło
2
+1 - działa to we wszystkich wersjach Windows i MS-DOS, w przeciwieństwie do zwykłego, if exist dirnamektóry wydaje się być specyficzny dla Windows NT.
grawity
to był głupi kod w porównaniu do linux mkdir -p myDirName: p
Kit Ho
6
Powinien to być ukośnik odwrotny, a nie ukośnik.
Nathan Garabedian
@grawity Co o tym sądzisz, najwyraźniej jakiś problem z robieniem \ nul? dostips.com/forum/viewtopic.php?f=3&t=4913
barlop
@barlop: Myślę, że cmd.exe jest jednym z najgorszych istniejących języków skryptowych i że należy w miarę możliwości używać programu PowerShell lub innych alternatyw. Co do tego \nul, nie jest już konieczne w Windows NT, zwykły if exist "C:\Program Files (x86)"powinien działać (chyba że nadal celujesz w Windows 98 ...)
grawity
11

Użyj ukośnika odwrotnego, a nie ukośnika: myDirName\nulniemyDirName/nul

md foo 
echo.>bar 
for %I in (foo bar xyz) do @( 
  if exist %I ( 
    if exist %I\nul ( 
      echo -- %I is a directory 
    ) else ( 
      echo -- %I is a file 
    ) 
  ) else ( 
    echo -- %I does not exist 
  ) 
)

- foo to katalog
- pasek to plik
- xyz nie istnieje

edycja: działa to tylko wtedy, gdy nazwa katalogu nie zawiera spacji

DVF
źródło
5

Niektórzy sugerują zrobienie \ nul, ale wydaje się, że nie działa to niezawodnie w NT

C:\blah>md abc

C:\blah>if exist abc\nul echo yes
yes

C:\blah>if exist "abc\nul" echo yes

C:\blah>

http://www.dostips.com/forum/viewtopic.php?f=3&t=4913

foxidrive writes-

The trick with nul worked in pre NT versions of windows.

Now you would use this, with a trailing backslash.

if exist "C:\abcde\" echo the folder exists

Re pytanie

C:\blah>if exist "abcd\" (echo yes) else (echo no && mkdir abcd)
no

C:\blah>if exist "abcd\" (echo yes) else (echo no && mkdir abcd)
yes

C:\blah>
barlop
źródło
4

Zastanawiałem się, dlaczego Joe miał głos negatywny, ponieważ miałem taki sam problem w systemie Windows 7, a mianowicie

JEŚLI ISTNIEJE nazwa pliku \ NUL

zwracał PRAWDA zarówno dla plików, jak i katalogów. Znalazłem alternatywne rozwiązanie na www.robvanderwoude.com/battech_ifexistfolder.php i opracowałem poprawioną wersję pętli FOR DVF:

FOR %I in (foo bar xyz) DO @( PUSHD %I && (POPD & echo -- %I is a directory) || ( IF exist %I ( echo -- %I is a file ) ELSE ( echo -- %I does not exist ) ) )
Damian
źródło
To było jedyne rozwiązanie, które zadziałało, dzięki. Dodałem „2> NUL”, aby uniknąć komunikatu o błędzie, i zmieniłem wartości echa na 1 (katalog istnieje), 0 (katalog nie istnieje), -1 (istnieje plik o tej samej nazwie) DLA% A IN („ C: \ temp \ foo \ HELLO WORLD5 ") DO @ (PUSHD"% A "2> NUL && (POPD & ECHO 1) || (JEŚLI ISTNIEJE% A (ECHO -1) ELSE (ECHO 0
Christoph
(przepraszam, nie udało mi się sformatować kodu jako kodu w odpowiedzi, chociaż próbowałem tak wielu rzeczy :-( do czasu edycji komentarza upłynął po 5 minutach :-()
Christoph
1

Widzę, że wielu ma problemy z rozróżnianiem plików i folderów. Czy ktoś próbował po prostu cd do niego po sprawdzeniu, czy istnieje? Wtedy cd albo się powiedzie, albo nie powiedzie.

set MyDir = "MyTestDir"
IF exist MyDir (
    cd MyDir 
    IF ERRORLEVEL NEQ 0 (
        echo "Error: %MyDir% already exists, but it is a file!"
        exit 1
    ) else (
        # Do not forget to cd back
        cd ..
    )
) else (
   # Did not exist yet, so create it.
   mkdir MyDir
)
Richard Rombouts
źródło
(1) Jeśli zamierzasz użyć zmiennej, użyj zmiennej. Wszystkie wystąpienia MyDirpo pierwszej linii powinny być %MyDir%. (2) cd ..Nie zrobi tego, co chcesz, jeśli %MyDir%jest to ścieżka wielopoziomowa (np. Pictures\cats) Lub nawet bezwzględna nazwa ścieżki (np \Windows.). Rozważ użycie pushd/ popdi / lub setlocal.
Scott
0
exist myDirName/nul

jest również prawdą, jeśli myDirName jest plikiem, co nie jest funkcją wyszukiwania

Joe
źródło
1
C:\blah>touch abe<ENTER>C:\blah>if exist abe\nul echo err<ENTER> C:\blah>if exist abe/nul echo err<ENTER>C:\blah>Nie jestem fanem \ nul w NT, ale tak nie jest. Powinieneś dać jakieś wyjście.
barlop
-1

Znalezienie folderu nie powinno być takie trudne. Moje rozwiązanie, użyj perla:

for ($ cnt = $ # ARGV; $ cnt> = 0; - $ cnt)
{
   if (-d „$ ARGV [$ cnt]”) { 
      print "argv [$ cnt] = $ ARGV [$ cnt] to folder \ n";
      $ dir = $ ARGV [$ cnt];
      przerwa;
   } else {
      print "argv [$ cnt] = $ ARGV [$ cnt] nie jest folderem \ n";
   }
}
użytkownik937229
źródło
Nie rozumiem
Pierre.Vriens