Як перевірити, чи існує каталог у Windows?


59

Я хотів би перекласти цей скрипт Linux / Bash у оболонку Windows:

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

Він перевіряє, чи існує каталог, і якщо він не створює його.


3
Фактична команда лінукс / баш буде просто: mkdir -p myDirName. Провівши дні, намагаючись перевести порівняно прості bash-скрипти в batch-sh * t (присвоївши результат функції змінній?), Я вирішив просто змусити людей встановлювати cygwin.
Майкл

Відповіді:


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

Додав Барлоп

Хоча вищезазначене працює для цієї конкретної ситуації, заголовок говорить про тестування спеціально для каталогу. Коментар Фогга if exist mydirname\скоріше використовується, а не if exist mydirnameспосіб. У деяких відповідях використовується \ nul, але \ nul проблематично в NT. Якщо не включати зворотну косу рису, буде тестуватися файл або каталог. Отже, для каталогу включіть зворотну косу рису.


23
Це правильно для тестування існування файлів, але як ви знаєте, що це каталог? Найпростіша відповідь - if exist mydirname\ і решта, як ви кажете. Крім того, ви можете фактично отримати testдвійковий файл і використовувати його в Windows.
фогг

@phogg: У ​​контексті цього конкретного питання: якщо він існує, але є файлом, ви все одно не можете цього mkdirзробити.
grawity

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

як я можу перевірити, чи не існує?
Сунггук Лім

1
@sunglim, написавши `Якщо не існує myDirName \` аналогічно if not 1==1 echo hmm або якщо існує myDirName \ ELSE blahblahblah
barlop

20

Ось що я тільки що дізнався:

Ви можете перевірити, чи існує файл нуля; якщо каталог існує, він буде містити файл nul, якщо файл nul не існує, то каталог не існує.

IF exist myDirName/nul ( echo myDirName exists ) ELSE ( mkdir myDirName && echo myDirName created)

2
+1 - це працює у всіх версіях Windows та MS-DOS, на відміну від звичайної, if exist dirnameяка видається специфічною для Windows NT.
grawity

це був дурний код порівняти з lkk mkdir -p myDirName: p
Kit Ho

6
Це повинен бути зворотний нахил, а не прямий нахил.
Натан Гарабедян

@grawity Що ти думаєш про це, мабуть, певна проблема з \ nul? dostips.com/forum/viewtopic.php?f=3&t=4913
barlop

@barlop: Я вважаю, що cmd.exe - це одна з найгірших мов сценаріїв, що існує, і для цього слід використовувати PowerShell або інші альтернативи, якщо це можливо. Що стосується \nul, це більше не потрібно в Windows NT, звичайна if exist "C:\Program Files (x86)"повинна працювати (якщо ви все ще не орієнтуєтесь на Windows 98 ...)
grawity

11

Використовуйте нахил, а не нахил вперед: myDirName\nulніmyDirName/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 - це каталог
- рядок - це файл
- xyz не існує

редагувати: це працює лише в тому випадку, якщо ім'я каталогу не містить пробілів


5

Деякі пропонують робити \ nul, але це, здається, не працює надійно в 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

Повторіть питання

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>

4

Мені було цікаво, чому у Джо утворився негативний результат, коли я відчував таку ж проблему в Windows 7, а саме це

ЯКЩО ІСНУЮТЬ ім'я файлу \ NUL

повертав TRUE як для файлів, так і для каталогів. Я знайшов альтернативне рішення на веб- сайті www.robvanderwoude.com/battech_ifexistfolder.php і придумав переглянуту версію циклу 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 ) ) )

Це було єдине рішення, яке спрацювало, дякую. Я додав "2> NUL", щоб уникнути повідомлення про помилку, і змінив значення ехо на 1 (каталог існує), 0 (каталог не існує), -1 (файл з такою ж назвою існує) FOR% A IN (" C: \ temp \ foo \ HELLO WORLD5 ") DO @ (PUSHD"% A "2> NUL && (POPD & ECHO 1) || (ЯКЩО ВІДСТАВЛЯЄТЬСЯ A (ECHO -1) ELSE (ECHO 0
Christoph

(вибачте, мені не вдалося відформатувати код як код у відповіді, хоча я спробував так багато речей :-( до редагування коментаря прогучав через 5 хвилин :-()
Крістоф

1

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

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
)

(1) Якщо ви збираєтесь використовувати змінну, використовуйте змінну. Усі випадки MyDirпісля першого рядка повинні бути %MyDir%. (2) Значення cd ..не буде робити те, що ви хочете, якщо %MyDir%це багаторівневе ім'я шляху (наприклад, Pictures\cats) або навіть абсолютна назва шляху (наприклад, \Windows). Розглянемо використання pushd/ popdта / або setlocal.
Скотт

0
exist myDirName/nul

також вірно, якщо myDirName - це файл, whis - це не функція, що шукається


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>Я не прихильник \ nul в NT, але це не так. Ви повинні були дати деякий результат.
барлоп

-1

Пошук папки не повинен бути таким складним. Моє рішення, використовуй perl:

для ($ cnt = $ # ARGV; $ cnt> = 0; - $ cnt)
{
   if (-d "$ ARGV [$ cnt]") { 
      print "argv [$ cnt] = $ ARGV [$ cnt] - папка \ n";
      $ dir = $ ARGV [$ cnt];
      перерва;
   } else {
      print "argv [$ cnt] = $ ARGV [$ cnt] - це не папка \ n";
   }
}

Я не розумію
Pierre.Vriens
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.