Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Операционные системы » Microsoft Windows » Задачи на bat-файлах 12

Модерирует : KLASS, IFkO

KLASS (06-03-2018 00:44): Объединение тем по сценариям: Сценарии Windows
 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83

   

hErAx

Редактировать | Цитировать | Сообщить модератору
Задачи на bat-файлах 12
Предыдущие части: (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
Вопросы, задачи и их решения по работе с командными файлами, а также сопутствующие ссылки.

 
Важно: копируя батник через буфер обмена из форума не забывайте удалять пробелы в конце каждой строки, т.к. в некоторых случаях из-за этого программа будет работать неправильно!!! Чтобы не копировались концевые пробелы из форума, жмите на ссылку "Редактировать" в посте, и уже из редактора копируйте батник без пробелов.
 
Также для удаления концевых пробелов пользуйтесь скриптом от Nagual, или VBS-Скрипт-Модулем от ViSiToR.
 
Для перекодирования кирилицы 866<—>1251 пользуйтесь онлайн сервисом Перекодировщик кириллицы

 
Дополняем шапку: добавляем готовые решения, полезные ссылки.
 
Примечание: Большие куски кода заключайте в тэг [more]  
 
Смежные темы:
В помощь системному администратору » Автоматизация администрирования
Программы » Командная строка, батники\сценарии
 
Полезные ссылки
 
Полезные утилиты
 
Готовые решения и частые вопросы:
  • При запуске batch-файла от Администратора текущая директория меняется на system32
  • Встроенный справочник по командам
  • Создание помощи по всем командам консоли 2000 и XP
  • Делаем паузу в командном файле стандартными средствами Windows
  • Альтернативные решения »
  • Работа с текстом, датой, и файлами »
  • Администрирование, автоматизация и сеть »
  • Работа с переменными и параметрами ком. строки »
     
    Описания работы команд и символов участниками темы:
    · setlocal enabledelayedexpansion и переменные окружения
    · символы & и && в командной строке
    · Переменная %0

  • Отправлено: 01:53 25-10-2015 | Исправлено: Paromshick, 21:51 18-12-2017
    AngelNet



    Gold Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    hErAux
    YuS_two
    отлично! то что было нужно

    ----------
    animelist

    Всего записей: 7414 | Зарегистр. 11-03-2004 | Отправлено: 00:04 13-10-2016
    chatt

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Elroir

    Цитата:
    Следующий код использует как раз ее (fciv.exe должен лежать в той же директории, что и командный файл или в одной из директорий, прописанных в переменной PATH):  

    Ухты, очень хорошо, спасибо! Но два момента по результатам тестирования очень просил бы допилить.
    1) Файл checksums.txt у меня в кодировке UTF-8, содержит символы юникода. После запуска батника всё, что кроме латиницы отображается в именах кракозябрами. Да, еще не заменяет старые имена файлов, а присоединяет к имени новое имя.
    2) Рекурсивно не работает, переименовал только файлы в указанной папке, в подпапках всё осталось. (checksums.txt содержит только хеши и имена, без путей подпапок). Очень хотелось получить инструмент, работающий независимо от путей подкаталогов.
    Надеюсь, всё получится, раз есть такая простая утилита.
     
    И еще момент, файл с хешами у меня очень большой, поэтому сначала нужно найти в нем посчитанный хеш, и если таковой имеется, то переименовать.
     
    Кстати, в шапке обнаружил еще fsum

    Всего записей: 186 | Зарегистр. 28-05-2016 | Отправлено: 00:39 13-10-2016 | Исправлено: chatt, 11:55 13-10-2016
    YuS_two



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    AntoshAReal  12-10-2016

    Цитата:
    скорее всего экранировал неправильно.

    Нет, cmd просто не очень предназначен для редактирования текста. А если конкретнее, Вы неправильно поняли суть вносимых изменений и работу команды findstr...
    Тут лучше привести исходный файл и целевой, который требуется получить... а средства для этого уже можно будет подобрать.  
    Посмотрите в сторону sed-а, им гораздо проще проделывать такие изменения.

    Всего записей: 399 | Зарегистр. 28-03-2016 | Отправлено: 07:20 13-10-2016
    AntoshAReal



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    YuS_two
    Вроде правильно думал. findstr с параметром /C отображат всё, кроме перечисленных строк, вот и думал что пусть всё печатает, кроме всего что ниже.
    Ну, возможно тогда на баше наваять, всё равно планируется переход на nix.
    Выше я указывал ссылку на свой пост, повторю в этом:
     

    Цитата:
     
    Суть в том, что есть файл proxy.pac, в его окончание необходимо добавить изменения.
    Этот файл будет скачиваться по крону и обрабатываться, внося необходимые изменения.
    В файле есть строки, содержащие:

    Код:
     
      if (proxify) {
        var isIE = /*@cc_on!@*/!1;
     
        if (isIE) {
          return "PROXY gw2.anticenz.org:8080; DIRECT";
        } else {
          return "HTTPS gw2.anticenz.org:443; PROXY gw2.anticenz.org:8080; DIRECT";
        }
      }
     
      return "DIRECT";
    }
     

     
    их необходимо заменить на несколько строк:

    Код:
     
        if (isIE) {
          return "PROXY proxy.antizapret.prostovpn.org:3128; DIRECT";
        } else {
          return "HTTPS proxy.antizapret.prostovpn.org:3143; PROXY proxy.antizapret.prostovpn.org:3128; DIRECT";
        }
      }
     
      if (dnsDomainIs(host, ".onion")) {
        return "PROXY 127.0.0.1:1080"; // tor proxy
      }
      if (dnsDomainIs(host, ".i2p")) {
        return "PROXY 127.0.0.1:1080"; // i2p proxy
      }
     
      return "DIRECT";
    }  
     

     

    Всего записей: 305 | Зарегистр. 31-08-2005 | Отправлено: 19:19 13-10-2016
    Elroir



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    chatt
     
    Выложи пример файла с хешами (несколько строчек, из тех, которые отображаются кракозябрами)


    ----------
    "В интернете есть все, но не всегда"

    Всего записей: 2631 | Зарегистр. 05-02-2003 | Отправлено: 23:05 13-10-2016
    Elroir



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    chatt
    Ладно, попробуем без примера.
    Задачка оказалась нетривиальная - cmd некорректно работатет с UTF-8 кодовой страницей. Некоторые встроенные утилиты, такие как find или more, перестают нормально работать.
    Кроме того, хотя существует очень много утилит для расчета MD5 - практически ни одна не умеет работать с неанглийскими именами файлов. В том числе fciv, fsum, fastsum (из шапки).
    Я нашел утилиту checksum, которая да умеет работать с UTF-8 из командной строки - 32 bit,  64 bit.
    Запускать setup.exe не надо - просто возьми из архива директорию "files\checksum"
     
    вот код:

    Код:
     
    @echo off
    setlocal
    pushd "%~dp0"
    for /f "tokens=4" %%a in ('chcp') do set "cp=%%a"
    chcp 65001 > nul
    set "folder=D:\TestHash"
    set "checksumFile=checksums.txt"
    checksum.exe crkq1m(*.*)j(filesList)d(%CD%) "%folder%"
    for /f "eol=# tokens=1*" %%a in (filesList.hash) do (
        call :cut "%%b"
        for /f "tokens=1*" %%A in ('findstr /C:"%%a" %checksumFile% 2^>nul') do (
            call :renFile "%%B"
        )
    )
    del filesList.hash
    popd
    chcp %cp% > nul
    goto :EOF
     
    :cut
    set "filePath=%~1"
    set "filePath=%filePath:~5%"
    goto :EOF
     
    :renFile
    echo Renaming "%filePath%" to "%~1"
    ren "%filePath%" "%~1"
     

     
    Kомандный файл должен быть в той же директории, что и checksum.exe.


    ----------
    "В интернете есть все, но не всегда"

    Всего записей: 2631 | Зарегистр. 05-02-2003 | Отправлено: 14:39 14-10-2016 | Исправлено: Elroir, 14:43 14-10-2016
    chatt

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Elroir
    http://rgho.st/8NccMvghD ex1.csv пример если сравнивать сначала размер, потом при совпадении хеш, и уже только тогда переименовывать. По времени работы было бы эффективнее. Если такой файл уже существует, переименовываем, добавляя суффикс перед расширением.
     
    Ваш код сейчас попробую, думаю, какой разделитель должен быть между колонками

    Всего записей: 186 | Зарегистр. 28-05-2016 | Отправлено: 19:30 14-10-2016 | Исправлено: chatt, 21:20 14-10-2016
    nik4z



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    AntoshAReal
    Как правильно заметил YuS_two, cmd не лучшее решение, с использованием сторонних утилит задача легко разрешима.
    Например, с помощью AutoIt3.exe решается в одну строчку батника.
     

    Код:
    AutoIt3.exe /AutoIt3ExecuteLine "$i=FileDelete('proxy1.pac')+FileWrite('proxy1.pac',StringReplace(FileRead('proxy.pac'),FileRead('search.txt'),FileRead('replace.txt')))"

     
    Здесь search.txt и replace.txt файлы с текстом, что и на что менять, важно только, чтобы в них кодировки совпадали.
    Можно и без них обойтись, вставив текст непосредственно в эту строку.

    Всего записей: 218 | Зарегистр. 08-11-2015 | Отправлено: 20:03 14-10-2016
    Elroir



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    chatt

    Цитата:
     думаю, какой разделитель должен быть между колонками

    Пробел.
     
    Насчет, размера файлов не понял - почему два сравнивания эффективнее одного?
    Кроме того, хеш уникальный, то есть по нему можно найти единственное совпадение, а размер может быть одинаковым для нескольких файлов.

    ----------
    "В интернете есть все, но не всегда"

    Всего записей: 2631 | Зарегистр. 05-02-2003 | Отправлено: 23:06 14-10-2016
    Pasha_ZZZ



    Platinum Member
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    Elroir
    Цитата:
    Насчет, размера файлов не понял - почему два сравнивания эффективнее одного?
    Ну во-первых, предлагалось считать хэш только при равенстве размера.
    Просто если размер файлов различается - сравнение хэша чуть менее, чем бессмысленно.
    Размер получается мгновенно, при подсчете хэша нужно не только прочитать весь файл, но и вычислить хэш по определенному алгоритму.

    Всего записей: 12375 | Зарегистр. 11-03-2002 | Отправлено: 23:11 14-10-2016
    Elroir



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Pasha_ZZZ
    Все так, если проходить по каждому файлу отдельно. Мой код сначала высчитивает хеш для каждого файла в директории и под-директориях, создавая список файлов с хешами, а потом просто ищет для каждого хеша совпадение. Так-как в изначальной задаче про размеры ничего не было сказано (то есть считать хеш для каждого файла было обязательно), я и не понял, как поможет сравнивание размера, если код все равно создает список всех файлов .
    Bottom line - согласен, пройтись по файлам и высчитать хеш только для тех, для которых существует строчка с таким же размером, эффективнее.
     
    chatt
    Несколько вопросов:
    1. Размер файлов указан в байтах?
    2. Шаблоном считать файл Ex1.csv (поля "Filesize","MD5","file_name")?
    3. Использовать в качестве разделителя запятую?


    ----------
    "В интернете есть все, но не всегда"

    Всего записей: 2631 | Зарегистр. 05-02-2003 | Отправлено: 00:00 15-10-2016
    chatt

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Elroir
    Число строк в csv на три порядка больше числа  файлов.
    1. В байтах
    2. Да, Ex1.csv - это шаблон.
    3. Разделитель - запятая, текст отделяется кавычками, UTF-8
    И если файл уже с таким именем существует, то перед расширением добавляем счетчик, напр. *_2.* или *(2).*

    Всего записей: 186 | Зарегистр. 28-05-2016 | Отправлено: 01:33 15-10-2016 | Исправлено: chatt, 01:38 15-10-2016
    AntoshAReal



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    nik4z
    Спасибо, попробую предложенный вами вариант.

    Всего записей: 305 | Зарегистр. 31-08-2005 | Отправлено: 19:05 15-10-2016
    YuS_two



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Elroir

    Цитата:
    Кроме того, хотя существует очень много утилит для расчета MD5 - практически ни одна не умеет работать с неанглийскими именами файлов. В том числе fciv, fsum, fastsum (из шапки).  

    А можно использовать, например, certutil - встроенное средство. Тут давеча попадался на другом форуме готовый сценарий для подсчета сумм...
    Ссылка в сценарии на исходный вариант автора.

    Код:
    @echo off
    rem http://www.cyberforum.ru/cmd-bat/thread671391-page5.html#post9646887
    for %%i in (certutil.exe) do (
        if not exist "%%~$PATH:i" goto:err
    )
    setlocal enabledelayedexpansion
    set "i=0"
    for %%i in (%*) do set /a "i+=1"
    if !i! equ 1 (
        call:sum "%~1"
        goto:eof
    )
    if !i! equ 2 (
        call:sum "%~1" "%~2"
        goto:eof
    )
    goto:man
    endlocal
    exit /b
     
    :err
    echo:Certutil has not been found.
    exit /b
     
    :man
    for %%i in (
        "Usage: %~n0 file [algorithm]"
        ""
        "Default algorithm is sha256."
        "Supported algorithms are md2, md4, md5,"
        "sha1, sha256, sha384 and sha512."
        ""
        "Note: this one was written and tested"
        "on Windows 7."
    ) do echo:%%~i
    pause
    exit /b
     
    :sum
    if not exist "%~1" goto:man
    if "%~2" equ "" (
        set "alg=SHA256"
    ) else (
        for /f "tokens=2 delims=:" %%i in ('2^>^&1 find "" %~2') do set "alg=%%i"
    )
    set "alg=!alg: =!"
    for /f "skip=1 delims=" %%i in ('certutil -hashfile "%~1" !alg!^| findstr /virc:"certutil"') do set "hash=%%i"
    if /i "!hash!" equ "" (
        echo:=^>err
    ) else (echo !hash: =!)
    exit /b

    для получения подсказки, просто запустить без параметров...

    Всего записей: 399 | Зарегистр. 28-03-2016 | Отправлено: 20:50 15-10-2016
    Koks1970

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Certutil -hashfile C:\image.png MD5 >> C:\out.txt

    Всего записей: 128 | Зарегистр. 15-01-2007 | Отправлено: 17:22 16-10-2016 | Исправлено: Koks1970, 17:24 16-10-2016
    Elroir



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    YuS_two

    Цитата:
    А можно использовать, например, certutil - встроенное средство

    Я ее пробовал - она работатет только с одним файлом за раз. А мне надо было рекурсивно по всем под-директориям.
    Но так-как условия задачи изменились - ее и буду использовать.
    Спасибо за пример!

    ----------
    "В интернете есть все, но не всегда"

    Всего записей: 2631 | Зарегистр. 05-02-2003 | Отправлено: 00:34 17-10-2016
    404NF

    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Подскажите, как узнать путь к образам запущенных процессов из командной строки? Нужно для создания пакетного файла или скрипта, завершающего все программы (портабельные), запущенные с определенного раздела, и не воздействующего на одноименные программы с других разделов.
    Подошел бы как вариант получения информации непосредственно от системы, так и утилита, возвращающая список вида "PID - путь к образу".
    Возможно, у данной задачи есть другие решения, кто знает - подскажите! Пока что пользуюсь специфическими именами окон для отдельных приложений, но это очень, очень кривой костыль.

    Всего записей: 250 | Зарегистр. 21-09-2013 | Отправлено: 01:00 17-10-2016
    hErAux



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    батник с таким содержимым
    wmic process Where (CommandLine like 'W:%%' OR CommandLine like '"W:%%') call Terminate
    будет закрывать процессы, запущенные с раздела W:

    Всего записей: 210 | Зарегистр. 08-04-2016 | Отправлено: 01:21 17-10-2016
    Elroir



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    chatt
     
    Код:

    Код:
     
    @echo off
    setlocal
    for /f "tokens=4" %%a in ('chcp') do set "cp=%%a"
    chcp 65001 > nul
    set "folder=D:\Downloads\ex1"
    set "checksumFile=ex1.csv"
    for /r "%folder%" %%a in (*.*) do (
        findstr /c:"%%~za," "%checksumFile%" 2>&1 1>nul
        if not errorlevel 1 (
            echo Found record with the same file size, checking the MD5 hash...
            call :calcMD5 "%%a"
            call :checkAndRename "%%a"
        )
    )
    popd
    chcp %cp% > nul
    goto :EOF
     
    :calcMD5
    for /f "skip=1 tokens=*" %%a in ('certutil -hashfile "%~1" MD5 ^| findstr /vic:"certutil" 2^>nul') do set "hash=%%a"
    set "hash=%hash: =%"
    echo   Calculated MD5 hash: %hash%
    goto :EOF
     
    :checkAndRename
    set "newName="
    for /f "tokens=2* delims=," %%a in ('findstr /ic:"%hash%" "%checksumFile%" 2^>nul') do set "newName=%%~b"
    if defined newName (
        echo   Matching record is found.
        if not "%~nx1"=="%newName%" (
            echo   Renaming "%~1" to "%newName%"
            ren "%~1" "%newName%"
        ) else (
            echo   Filenames are the same
            rem Add counter to the filename
        )
    ) else (
        echo   No maching record is found
    )  
    goto :EOF
     

     
    Если имена файлов совпадают - счетчик не добавляется (слишком много вариантов надо проверить, чтобы выделить уже существующее число из имени). Я оставил место для этой логики - там где строчка "rem Add counter to the filename".

    ----------
    "В интернете есть все, но не всегда"

    Всего записей: 2631 | Зарегистр. 05-02-2003 | Отправлено: 01:40 17-10-2016 | Исправлено: Elroir, 12:10 17-10-2016
    YuS_two



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Elroir  17-10-2016

    Цитата:
    она работатет только с одним файлом за раз. А надо было рекурсивно по всем под-директориям.

    Вообще, мне показалось, что проблема с выбором утилиты... хотя на самом деле таких утилит масса и для работы в консоли тоже.  
    Просто certutil - встроенное средство и работать будет почти везде, где она присутствует по умолчанию.
    А рекурсивный проход по файлам - это разве проблема?

    Код:
    for /f "delims=" %%i in ('dir /a-d/s/b "c:\TEST"') do (
        ...
    )

    Всего записей: 399 | Зарегистр. 28-03-2016 | Отправлено: 04:53 17-10-2016
       

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83

    Компьютерный форум Ru.Board » Операционные системы » Microsoft Windows » Задачи на bat-файлах 12
    KLASS (06-03-2018 00:44): Объединение тем по сценариям: Сценарии Windows


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2024

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru