Поиск файла и возможность выбора из нескольких найденных

Тема в разделе "Пакетные файлы CMD, BAT", создана пользователем alex_diablo, 7 июл 2015.

  1. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    Задача:
    на файловой шаре, где много разного софта в куче разных вложенных подкаталогов есть прога (в данном случае Unity), у которой много разных версий (3.0.1, 3.0.2 ... 4.5.1, 4.5.2 и тд.). Все (или почти все) версии лежат каждая в отдельной папке (папки не обязательно пронумерованы по версии, вернее название папки может отличаться от шаблоны), установочные файлы именуются в виде: Unity_ver.4.6.1, setup_5.2.1 и т.д. т.е. каждая (почти каждая) версия пронумерована в соответствии с шаблоном вида *x.x.x.exe. нужно было сделать батник, в котором при вводе искомой версии установочного файла находился бы путь и подставлялся бы дальше в код скрипта (для дальнейшей установки на компы через psexec. после всех манипуляций с поиском, после нахождения полного пути до установочного файла, формируется автоматом другой батник и рассылается на требуемые компы.

    сделал это так:

    Код (Text):
    rem вводим версию
    set /p version=" >>  Enter required version of Unity: "

    rem ищем путь
    where/r \\server\soft\Unity\ *%version%.exe >temp.txt
    дальше переменную fulpath мы уже используем для подстановки в качестве пути для установки софта через psexec.

    и все вроде бы хорошо, если например, вводишь 4.5.1 и файл с такими цифрами существует,
    выводится полный путь с именем файла, который записываем во временный файл, а далее
    записываем в переменную и уже используем где нужно:

    Код (Text):
    set /p fullpath="" <temp.txt
    Но на определенном этапе можно столкнуться с проблемой, что может оказаться два или более
    одиннаковых результатов поиска (например: файл Unity_4.5.2.exe , который лежит в двух папках - x64 и х86, имя одинаковое, но разрядность разная, стало быть, разные файлы и лежат в разных местах). в этом случае в файл temp.txt скопируются все найденные пути, например:

    Код (DOS):
    \\server\soft\5.5.0\x86\unity_setup_5.5.0.exe
    \\server\soft\5.5.0\x64\unity_setup_5.5.0.exe
    \\server\soft\5.5.0\unity_setup_5.5.0.exe
    но при последующей записи в переменную попадет только одна строка, в данном случае - первая в файле.
    как быть в этом случае? как выбрать нужный файл? и как вообще узнать, один файл найден или несколько? можно конечно переименовать все файлы по шаблону, добавить в имя файла указание разрядности, чтобы поиск версии гарантированно выдавал только 1 файл, но это дополнительный ввод параметров при поиске... такое нежелательно.

    частично сделал так:

    Код (Text):
     rem читаем файл, считаем количество строк и в отдельный файл записываем цифру, равную количеству строк:
    find /c /v "" <"temp.txt" >string.txt

    rem из временного файла с одним лишь символом (цифрой, обозначающей количество строк в файле temp.txt), записываем этот символ в переменную:
    set /p string="" <string.txt

    rem проверка на кол-во строк: если =1, то выполняется дальше условие по установке (через метку goto переходим к нужной части скрипта).
    if %string%==1 goto install

    rem если цифра больше 1, то выводится сообщение, вида:
    echo    More then one path was founded:

    rem и ниже выводим все строки с найденными путями:
    echo.
    type host2.txt
    и вот на этом шаге нужно предложить юзеру выбрать нужный путь. но я не знаю, как сделать это
    с использованием меню? например - у нас 3 файла в разных путях, нужно, чтобы юзер мог нажать
    1, 2 или 3, в зависимости от того, какой путь ему интересен. желательно конечно, чтобы возле каждого пути стояла цифра кнопки, которую нужно нажать.

    думается, делать это можно через choice и if errorlevel
    но как правильно увязать это с результатами поиска я не знаю, на ум приходит только так:

    Код (Text):
    set /p path=" >> type path manually: "
    но это совсем не то, ибо вводить длиннющий путь вручную некрасиво и неудобно, теряется вообще смысл батника.
    хотелось бы, чтобы в случае нахождения нескольких путей до файлов (например 3 файла) выводилось бы на экран что то типа этого:

    Код (DOS):
    "найдено n-файлов по заданной маске в следующих директориях:"

    1 \\server\soft\5.5.0\x86\unity_setup_5.5.0.exe
    2 \\server\soft\5.5.0\x64\unity_setup_5.5.0.exe
    3 \\server\soft\5.5.0\unity_setup_5.5.0.exe

    "выберите нужный файл"
    т.е. по нажатию клавиш 1, 2 или 3 - у нас

    прошу помощи в реализации задумки :) надеюсь, смысл задумки понятно объяснил...
    зы. возможно, алгоритм поиска версии можно сделать по другому, лучше и проще и обойтись
    без подсчета количества строк и записи все в отдельный файл...
    буду рад любой помощи, включая оптимизацию кода)
     
  2. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Если цель - сделать как можно проще, то может номер версии вообще не вводить?

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

    Код (DOS):
    @echo off
    SetLocal EnableExtensions

    set "Folder=\\server\soft\Unity"

    set n=0

    For /f "delims=" %%a in ('dir /b /s /a-d "%Folder%\setup*.exe" "%Folder%\Unity*.exe"') do (
      set /a n+=1
      call set name[%%n%%]=%%~na
      call set path[%%n%%]=%%~fa
      call echo %%n%%.  %%~na    -   %%~fa
    )
    echo.
    if %n%==0 (echo No Files! & pause & goto :eof)

    :dialog
    set /p "ch=Enter number and press ENTER: "
    if "%ch%"=="" goto dialog
    if %ch% GTR %n% goto dialog

    call set mypath=%%path[%ch%]%%
    echo.
    echo Your choice is: %mypath%
    echo.
    pause
     
     
  3. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    скрипт ваш не запустился...
    по поводу почему идет привязка к номеру версии: - потому что это фактически единственное, что делает конкретный файл уникальным, потому что файлы разных версий могут обзываться совершенно по-разному. где-то используется слово unity, где-то setup ... а цифровая версия почти во всех случаях уникальна. изначально от этого и плясали. на грабли наткнулись лишь тогда, когда случайно обнаружили (увидели и вспомнили), что по забывчивости или по глупости, где-то могут оказаться файлы разных разрядностей. опять же - зачем отображать все файлы (их может оказаться до сотни в итоге, если не больше) всех версий, если задача состоит в конкретизации. по сути пользователю известно точно, какую версию ему нужно установить. он не будет выбирать. для этого и нужно всего лишь указать конкретную версию, а просмотреть все существующие при необходимости можно и просто открыв шару. задача скрипта - максимально упростить раскатывание данного софта скажем, на 10 машин, делая это в несколько кликов.

    во вложении - как выглядит папка со всеми подпапками всех версий и как выглядит подпапка с какой-либо конкретной версией (там лежат еще и установочные файлы для macOS, а нам требуется разумеется, только для винды)... как-то так.
     

    Вложения:

    • unity1.JPG
      unity1.JPG
      Размер файла:
      32 КБ
      Просмотров:
      1
    • unity2.JPG
      unity2.JPG
      Размер файла:
      26,7 КБ
      Просмотров:
      1
  4. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Это в смысле как не запустился, как запускали и что произошло?
     
  5. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    таки заработал. первый раз запускал с рабочего стола. запустил с корня диска - заработало.
    но как я уже написал выше, результат немного не тот, что нужен. вроде постарался максимально подробно описать причину и суть, почему нужно через номер версии.
    вроде как то, что нужно, но не нужно делать вывод полностью всех файлов, задача как раз стоит в том, чтобы максимально сузить поиск.
    еще раз: версия известна. неизвестно - где лежит. (нахождение одной и той же версии в разных местах - побочный эффект, и из за этого есть вероятность установки не того файла или не из той директории). поэтому и нужно сделать в случае вышеобозначенного побочного эффекта возможность лицезреть все найденное для принятия правильного решения...
     

    Вложения:

    • unity3.JPG
      unity3.JPG
      Размер файла:
      82,5 КБ
      Просмотров:
      1
    Последнее редактирование: 7 июл 2015
  6. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Может потому что я в скрипте свой путь оставил, потом отредактировал...

    Если по номеру версии, тогда так:
    Код (DOS):
    @echo off
    SetLocal EnableExtensions

    set "Folder=\\server\soft\Unity"

    set n=0

    set /p "vers=Enter version: "

    For /f "delims=" %%a in ('dir /b /s /a-d "%Folder%\setup*.exe" "%Folder%\Unity*.exe" ^| find "%vers%"') do (
      set /a n+=1
      call set name[%%n%%]=%%~na
      call set path[%%n%%]=%%~fa
      call echo %%n%%.  %%~na    -   %%~fa
    )
    echo.
    if %n%==0 (echo No Files! & pause & goto :eof)

    :dialog
    set /p "ch=Enter number press ENTER: "
    if "%ch%"=="" goto dialog
    if %ch% GTR %n% goto dialog

    call set mypath=%%path[%ch%]%%
    echo.
    echo Your choice is: %mypath%
    echo.
    pause
    --- Объединённое сообщение, 7 июл 2015 ---
    Можете и свою команду:
    Код (Text):
    where/r \\server\soft\Unity\ *%version%.exe
    вставить в скрипт, если ее работа Вас целиком удовлетворяла. Будет:
    Код (Text):
    For /f "delims=" %%a in ('where /r \\server\soft\Unity\ *%vers%.exe') do (
     
    Kиpилл нравится это.
  7. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    вот уже лучше... а нельзя ли добавить условие-проверку, что если: найденный путь всего один, то не просить ничего нажимать, а сразу передавать этот путь в переменную fullpath. дабы не делать лишнего действия. изначально старался сводить нажатия клавиш к минимуму.
    но если (как я и озвучивал условие выше) путей нашлось 2 или более - то тогда уже выводить меню выбора.

    и нельзя ли таки обыграть вывод пути через choice, чтобы не нужно было набирать номер пункта, а просто нажимать кнопку, которая соответсвует номеру ?
     
    Последнее редактирование: 7 июл 2015
  8. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Обратите внимание, что в XP нет встроенной утилиты choice.
    По остальным замечаниям:

    Код (DOS):
    @echo off
    SetLocal EnableExtensions

    set "Folder=\\server\soft\Unity"

    set n=0

    set /p "vers=Enter version: "
    echo.

    For /f "delims=" %%a in ('dir /b /s /a-d "%Folder%\setup*.exe" "%Folder%\Unity*.exe" ^| find "%vers%"') do (
      set /a n+=1
      call set name[%%n%%]=%%~na
      call set path[%%n%%]=%%~fa
    )
    if %n%==0 (echo No Files! & pause & goto :eof)
    if %n%==1 (set "ch=1" & goto EndDialog)
    :dialog
    For /L %%C in (1,1,%n%) do call echo %%C.  %%name[%%C]%%    -   %%path[%%C]%%
    echo.
    if %n% LSS 10 (
      choice /C 123456789 /M "Enter number: " /N
      call set ch=%%errorlevel%%
    ) else (
      set /p "ch=Enter number press ENTER: "
    )
    if "%ch%"=="" goto dialog
    if %ch% GTR %n% goto dialog
    if %ch% LSS 0 goto dialog
    :EndDialog

    call set mypath=%%path[%ch%]%%
    echo.
    echo Your choice is: %mypath%
    echo.
    pause
     
    ScriptMakeR и Kиpилл нравится это.
  9. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    большое спасибо! реализовано все, что нужно! все работает отлично!
    --- Объединённое сообщение, 8 июл 2015, Дата первоначального сообщения: 8 июл 2015 ---
    в продолжении темы... есть похожая задача, вернее, она предшествует скрипту выше:

    Итак: прежде, чем выполнить скрипт по поиску нужной версии программы, нужно определиться,
    на какой комп (ы) будем ее устанавливать.
    Для этого через net view выполняем поиск всех хостов. У нас на всех компах в сети присутствует описание компа (имя и фамилия пользователя), поэтому поиск можно осуществлять по фио.
    все хосты вида подразделение-первая буква имени и фамилия:
    msk-aivanov
    msk-bpetrov

    все имена хостов - не длиннее 15 символов, т.е. если по шаблону не получается уместить полностью фио и уложиться в 15 символов, просто обрезаем конец фамилии, либо что-то подобное: msk-dpervoproh (в описании напротив хоста будет: dmitry pervoprohodcev)
    итак, для поиска хоста мы можем забить либо часть фио, которая будет частью хоста, либо ввести полностью: dmitry pervoprohodcev
    далее скрипт должен в файле найти нужный хост и записать его в переменную (для дальнейшей работы с ним при использовании скрипта для установки выше)
    проблема в том, что у некоторых юзеров может быть 1, 2 или даже 3 компа (ноута), хосты у них будут немного отличаться (буква, цифра и тд.), а описание будет одинаковое (фио)
    поэтому нужна возможность выбора в случае чего.
    ниже мой кривой :) код:

    Код (DOS):
    @echo off
    rem ищем все хосты и записываем в файл.
    net.exe view > host1.txt
    setlocal
    :1
    cls
    echo.
    echo.
    set /p name=" >> Enter the name of user: "
    rem в списке всех найденных хостов находим нужный и записываем в другой файл
    findstr /i /c:"%name%" host1.txt > host2.txt
    rem тут проверяем, найден ли какой-либо хост по шаблону поиска
    if %errorlevel%==1 goto 2
    rem если  хост найден не один, считаем количество найденных хостов и в еще один файл записываем цифру, равную количеству строк
    find /c /v "" <"host2.txt" >string.txt
    set /p string="" <string.txt
    rem если строка 1
    rem если хост один, идем на шаг 3
    if %string%==1 goto 3
    cls
    echo.
    echo    More then one HOST was founded:
    echo.
    echo.
    rem выводим список всех найденных (похожих хостов)
    type host2.txt
    echo.
    echo.
    echo   1 Type HOST manually
    echo   2 Back to the main menu
    echo   3 Exit
    echo.
    echo.
    choice /C:123 /m "choose your action:"
    if errorlevel 3 goto exit
    if errorlevel 2 goto 1
    if errorlevel 1 goto a
    :a
    cls
    echo.
    echo.
    type host2.txt
    echo.
    echo.
    rem смотрим список найденных хостов выше и вводим нужный
    set /p host=" >> type hostname manually: "
    rem на всякий случай, проверяем доступность хоста (вдруг внезапно выключили комп)))
    ping %host% | find /i "ttl"
    if %errorlevel%==1 goto 2
    rem если хост найден, записываем его (тот самый хост, который нужен. в дальнейшем, psexec будет подставлять этот файл для установки софта на комп, который указан в этом файле)
    echo %host% > hosts_exist.txt
    goto exit
    :2
    echo host for %name% not found. Try to type the name again.
    echo.
    endlocal
    choice /C:12 /m "> choose your action:"
    if errorlevel 2 goto exit
    if errorlevel 1 goto 1
    :3
    cls
    set /p host="" <host2.txt
    rem обрезаем все лишнее (убираем \\ и описание компа. оставляем только 15 символов)
    set host=%host:~2,15%
    ping %host% | find /i "ttl"
    if %errorlevel%==1 goto 2
    echo %host% > hosts_exist.txt
    echo.
    echo.
    echo   host %host% is ready.
    echo.
    choice /C:12 /m "> choose your action:"
    echo.
    endlocal
    if errorlevel 2 goto exit
    if errorlevel 1 goto 1
    :exit
    del host1.txt
    del hosts_exist.txt
    del host2.txt
    del string.txt
    только не кидайте сразу шапками пожалуйста)) согласен, скрипт УГ и сделан на коленке) увы, пока еще только начинаю этим заниматься и с циклами пока что очень плохо получается (но начальство ставит задачи, которые нужно каким-то образом выполнять).
    поэтому буду признателен за помощь в оптимизации кода, возможно на примере предыдущего скрипта, как я понимаю, ситуация здесь примерно похожа? только ищем мы не пути файлов, а строки с хостами...
     
  10. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Просто - это не означает, что плохо.

    Код (DOS):
    @echo off
    rem ищем все хосты и записываем в файл.
    net.exe view > host1.txt
    echo.
    :1
    cls
    :1a
    echo.
    set /p name=" >> Enter the NAME of user: "
    rem в списке всех найденных хостов находим нужный и записываем в другой файл
    set n=0
    for /F "delims=" %%a in ('findstr /i /c:"%name%" host1.txt') do (
      set /a n+=1
      call set host[%%n%%]=%%a
    )
    rem тут проверяем, найден ли какой-либо хост по шаблону поиска
    rem ни одного хоста не найдено
    if %n%==0 (echo No names! & goto 1a)
    rem если хост один, идем на шаг 3
    if %n%==1 goto 3
    rem если хостов найдено несколько, выводим их все и предлагаем указать цифру соответствующую этому хосту
    echo.
    echo    More then one HOST was founded:
    :ch1
    cls
    :ch1a
    echo.
    rem выводим список всех найденных (похожих хостов)
    For /L %%C in (1,1,%n%) do call echo   %%C.  %%host[%%C]%%
    echo.
    echo   0 - Back to the main menu
    echo.
    if %n% GTR 9 (
      set /p "ch=Type HOST number and press ENTER: "
    ) else (
      choice /C 1234567890 /m "Type HOST number: " /N
      call set ch=%%errorlevel%%
    )
    if %n% LSS 10 if %ch%==10 goto 1
    if %ch% GTR %n% goto ch1
    if %ch% LSS 0 goto ch1

    call set host=%%host[%ch%]%%
    echo Your choice: %host%

    :3
    rem обрезаем все лишнее (убираем \\ и описание компа. оставляем только 15 символов)
    set host=%host:~2,15%

    :: Проверяем доступность хоста

    ping %host% | find /i "ttl" || (
      echo host for %name% not found.
     rem Хост был только 1, предлагаем провести новый поиск по имени
      if %n%==1 goto 1a
     rem Хостов было найдено больше 1, предлагаем ввести новый номер похожего хоста.
      goto ch1a
    )

    rem если хост найден, записываем его (тот самый хост, который нужен. в дальнейшем, psexec будет подставлять этот файл для установки софта на комп, который указан в этом файле)


    echo %host% > hosts_exist.txt
    echo.
    echo.
    echo   host %host% is ready.
    echo.
    echo.
    echo 1 - Find new name
    echo 2 - Exit
    echo.
    choice /C:12 /m "> choose your action: "
    if %errorlevel%==1 goto 1
    :exit
    del host1.txt
    del hosts_exist.txt
     
    Kиpилл и ScriptMakeR нравится это.
  11. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    а одинаковые имена переменных в этом и предыдущем коде в одном скрипте не будут пересекаться и мешать работе друг друга?

    зы. почему то не находит по имени и фамилии. т.е. пишешь: ivan petrov - пишет хост нот фаунд. но если вводишь только ivan или petrov, то выводит все найденные по маске хосты... где косяк?
     
    Последнее редактирование: 8 июл 2015
  12. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    в команде findstr. Я скопипастил, не обратив внимание.
    Перепишите участок кода с использованием команды find:
    Код (Text):

    for /F "delims=" %%a in ('2^>NUL find /i "%name%" ^< host1.txt') do (
     
    Если все равно не сработает, пришлите файл host1.txt (именно в виде файла!) (можно только с той строкой, которую не находит).

    Пересечение только на переменной n.
    Пока код выполняется последовательно, без перекрестных вызовов (а здесь иначе и не будет), все будет хорошо.
    Я даже SetLocal из этого кода убрал, зная что возможно, захотите зациклить оба кода по кругу.
    Иначе это могло привести к переполнению стека и вылету.
    --- Объединённое сообщение, 8 июл 2015 ---
    На счет того, что переменные не очищаются, здесь маркером служит та самая переменная n.
    Как видите, в обоих случаях, ей сперва присваивается 0.
    Условные проверки с другими переменными не используются.
     
  13. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    сделал так:

    Код (DOS):
    for /F "delims=" %%a in ('find /i host1.txt "%name%"') do (
    поиск заработал, строка находится, но результат выглядит так:

    Код (Text):

      1.  ---------- HOST1.TXT
      2.  \\MSK-AAIVANOV           Alexander Ivanov
      3.  \\MSK-APETROV          Alexander Petrov
      4.  \\MSK-ASIDOROV         Alexander Sidorov
     
      0 - Back to the main menu

    Type HOST number:
    т.е. в качестве первого пункта, который можно выбрать, у нас выступает имя файла, как от этого избавиться?

    up:

    если делаю так:

    Код (DOS):
    for /F "delims=" %%a in ('2^>NUL find /i "%name%" ^< host1.txt') do (
    поиск срабатывает, и выглядит все так:

    Код (Text):
      1.  \\MSK-AAIVANOV           Alexander Ivanov
      2.  \\MSK-APETROV          Alexander Petrov
      3.  \\MSK-ASIDOROV         Alexander Sidorov
    но только если поиск делать лишь по имени или только по фамилии.
    если я ввожу Alexander Ivanov, то результат команды:

    Код (Text):
    >> Enter the NAME of user: Alexander Ivanov
    host for Alexander Ivanov not found.
     
    Последнее редактирование: 8 июл 2015
  14. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    ......
    Только не копируйте конкретную строку в другой файл -> удалите все лишнее из исходного и сохраните.
    Хочется взглянуть что там в качестве разделителя у команды net view.
    Сейчас нет доступа ни к каким сеткам, чтобы на чем то живом проверить.
    --- Объединённое сообщение, 8 июл 2015 ---
    Ну а в целом должно вот так заработать:

    Код (DOS):
    for /F "skip=1 delims=" %%a in ('2^>NUL find /i host1.txt "%name%"') do (
     
  15. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    файл во вложении
    --- Объединённое сообщение, 8 июл 2015, Дата первоначального сообщения: 8 июл 2015 ---
    если делаю так

    Код (DOS):
    for /F "skip=1 delims=" %%a in ('2^>NUL find /i host1.txt "%name%"') do (
    то результат такой:

    Код (Text):
     1.  ---------- HOST1.TXT
      2.  \\MSK-AAIVANOV           Alexander Ivanov
      3.  \\MSK-APETROV          Alexander Petrov
      4.  \\MSK-ASIDOROV         Alexander Sidorov
      0 - Back to the main menu

    Type HOST number:
    т.е. имя файла участвует в выборе пункта меню и его можно нажать по цифре 1.
    соответственно в результате получим лажу...
     

    Вложения:

    • host1.txt
      Размер файла:
      353 байт
      Просмотров:
      4
    Последнее редактирование модератором: 8 июл 2015
  16. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    У меня с этим файлом все отрабатывает нормально (имя+фамилия). Не могу установить причину проблемы.
    Какая версия ОС?

    Чтобы убрать шапку, нужно пропустить больше строк.
    Напишите:
    Код (DOS):
    for /F "skip=2 delims=" %%a in ('2^>NUL find /i host1.txt "%name%"') do (
     
  17. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    win 7 pro x64 rus
    --- Объединённое сообщение, 8 июл 2015 ---
    вот именно так:
    Код (DOS):
    for /F "skip=2 delims=" %%a in ('2^>NUL find /i host1.txt "%name%"') do (
    у меня по имени и фамилии (alexander sidorov) не находит.
    только по alexander или только по sidorov.
    не пойму, где собака порылась...

    т.е. если не использовать skip, то все ищется, но в пункте меню 1 выводится имя файла. если ставлю skip=1, все то же самое, но если ставлю skip=2 - перестает находить.
     
    Последнее редактирование модератором: 8 июл 2015
  18. Dragokas
    Оффлайн

    Dragokas Very kind Developer Команда форума Супер-Модератор Разработчик Клуб переводчиков

    Сообщения:
    4.478
    Симпатии:
    4.307
    Ага. Нашел. Ошибка совсем в другом месте.
    Когда находит только 1 совпадение, переменной host ничего не присваивается.
    Вот исправленный код:

    Код (DOS):
    @echo off
    rem ищем все хосты и записываем в файл.
    net.exe view > host1.txt
    echo.
    :1
    cls
    :1a
    echo.
    set /p name=" >> Enter the NAME of user: "
    rem в списке всех найденных хостов находим нужный и записываем в другой файл
    set n=0
    for /F "skip=2 delims=" %%a in ('2^>NUL find /i host1.txt "%name%"') do (
      set /a n+=1
      call set host[%%n%%]=%%a
      set host=%%a
    )
    rem тут проверяем, найден ли какой-либо хост по шаблону поиска
    rem ни одного хоста не найдено
    if %n%==0 (echo No names! & goto 1a)
    rem если хост один, идем на шаг 3
    if %n%==1 goto 3
    rem если хостов найдено несколько, выводим их все и предлагаем указать цифру соответствующую этому хосту
    echo.
    echo    More then one HOST was founded:
    :ch1
    cls
    :ch1a
    echo.
    rem выводим список всех найденных (похожих хостов)
    For /L %%C in (1,1,%n%) do call echo   %%C.  %%host[%%C]%%
    echo.
    echo   0 - Back to the main menu
    echo.
    if %n% GTR 9 (
      set /p "ch=Type HOST number and press ENTER: "
    ) else (
      choice /C 1234567890 /m "Type HOST number: " /N
      call set ch=%%errorlevel%%
    )
    if %n% LSS 10 if %ch%==10 goto 1
    if %ch% GTR %n% goto ch1
    if %ch% LSS 0 goto ch1

    call set host=%%host[%ch%]%%

    :3
    echo Your choice: %host%
    rem обрезаем все лишнее (убираем \\ и описание компа. оставляем только 15 символов)
    set host=%host:~2,15%

    :: Проверяем доступность хоста

    ping %host% | find /i "ttl" || (
      echo host for %name% not found.
    rem Хост был только 1, предлагаем провести новый поиск по имени
      if %n%==1 goto 1a
    rem Хостов было найдено больше 1, предлагаем ввести новый номер похожего хоста.
      goto ch1a
    )

    rem если хост найден, записываем его (тот самый хост, который нужен. в дальнейшем, psexec будет подставлять этот файл для установки софта на комп, который указан в этом файле)


    echo %host% > hosts_exist.txt
    echo.
    echo.
    echo   host %host% is ready.
    echo.
    echo.
    echo 1 - Find new name
    echo 2 - Exit
    echo.
    choice /C:12 /m "> choose your action: "
    if %errorlevel%==1 goto 1
    :exit
    del host1.txt
    del hosts_exist.txt
     
  19. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    спасибо! теперь все отлично!
     
  20. alex_diablo
    Оффлайн

    alex_diablo Пользователь

    Сообщения:
    104
    Симпатии:
    7
    добавил в код дополнительный пункт меню - 0:

    Код (DOS):
    For /L %%C in (1,1,%n%) do call echo %%C.  %%name[%%C]%%
    echo.
    echo 0. choice another version
    echo.
    if %n% LSS 10 (
      choice /C 123456789 /M "Enter number: " /N
      call set ch=%%errorlevel%%
    ) else (
      set /p "ch=Enter number press ENTER: "
    )
    if "%ch%"=="" goto dialog
    if %ch% GTR %n% goto dialog
    if %ch% LSS 0 goto dialog
    if %ch%==0 goto single_setup
    т.е. если после того, как на экран выводится список меню, ниже есть 0, т.е. по нажатию возвращаемся к началу. но не работает, если в меню меньше 10 пунктов. если больше 10, то при ручном вводе цифры 0 и по нажатию enter все срабатывает. где косяк?

    и еще один баг обнаружил, когда в меню больше 10 пунктов:

    если ввести например 23 и в меню есть этот пункт, все ок. если мы нажимаем например 23. , то скрипт не срабатывает, ок. но если мы наберем 2.3 , скрипт делает так, как должен при положительном результате срабатывать, но при этом ничего в пути не показывает... вроде бы логично, что не нужно так нажимать, но если нажать, скрипт продолжает работу не выполнив предыдущего пункта... неприятно... не знаю как пофиксить...
     
    Последнее редактирование: 9 июл 2015

Поделиться этой страницей