Ru-Board.club
← Вернуться в раздел «Microsoft Windows»

» Задачи на bat-файлах 4

Автор: 01MDM
Дата сообщения: 05.11.2007 09:20
Elroir
Да не работает. Показывает последний из больших найденных файлов (>=2147483648)
Автор: yurkesha
Дата сообщения: 05.11.2007 11:06
Elroir
Вот теперь понятно. К моему коду тоже есть замечания?
Автор: Elroir
Дата сообщения: 05.11.2007 11:42
yurkesha

Цитата:
К моему коду тоже есть замечания?

Не то чтобы замечания...
Если я правильно понял (запустить сейчас нет возможности), он записывает во временный файл размеры всех файлов в директории и поддиректориях. У нас цель, все-таки, найти самый большой файл, поэтому, на мой взгляд, эффективнее будет для каждой поддиректории запускать и обрабатывать "dir /os", и записывать во временный файл только самый большой файл в директории.


Добавлено:
Вообще - это, конечно, усложняет код (вытаскивать из dir-а размер и т.д). Поэтому - замечаний нет
Автор: yurkesha
Дата сообщения: 05.11.2007 12:20
Да это в принципе как раз роли не играет... Я о другом - есть принципиально два разных подхода на сравнение чисел:
- сравнить как числа
- выровнять до одинаковой длины добив нулями слева и сравнить как стринги.
И я применил именно второй подход. В отличии от первого он легко масштабируется по разрядности(то что я называл порядок ограничения в 100 терабайт на самом деле означает цифири в 900 с копейками терабайт).
А во временный файл действительно пишутся размеры абсолютно всех файлов, хотя на выходе и имеем только один - максимальный.
Автор: Elroir
Дата сообщения: 05.11.2007 13:12
yurkesha
Оба подхода имеют равные права на существование. Оба делают, то что нужно.
Как ты и сказал - если сравнивать как числа, получается два сравнения, а если строчки одно. В данном случае, все зависит от того, кому как удобно.
А насчет того, что код проходит по всем файлам - представь, что на диске есть несколько десятков или сотен тысяч файлов...
Автор: yurkesha
Дата сообщения: 05.11.2007 13:22
Elroir как ты думаешь - может ли код индивидуального сравнения внутри цикла превзойти по скорости команду SORT? Вообще интересно было бы проверить
Автор: king_stiven
Дата сообщения: 05.11.2007 13:43
yurkesha
Как правило все операции с временными файлами нагружают комп, замедляют работу. Кстати я свой код подправил, сравнивал по времени с 01MDM, скорость в 2 раза выше.
Автор: Elroir
Дата сообщения: 05.11.2007 13:58
yurkesha

Цитата:
как ты думаешь - может ли код индивидуального сравнения внутри цикла превзойти по скорости команду SORT?

Не думаю, что может.
Я не то имел в виду. SORT пусть сортирует
Но ведь цикл проходит по всем файлам, для каждого файла берется его размер и записывается во временный файл. Вот я и предложил, вместо того чтобы обрабатывать каждый файл, брать из dir-a только один - самый большой в данной директории и записывать в файл (для последующей сортировки) только его.
Автор: king_stiven
Дата сообщения: 05.11.2007 14:20
yurkesha
Твой скрипт довольно шустро пашет.
Автор: Elroir
Дата сообщения: 05.11.2007 16:46
yurkesha
Выигрыш во времени при использовании dir-a на примерно 70000 файлов, получается около 20 процентов (твой код работал 5 мин., мой - 4 мин.)
Автор: Tipulatoid
Дата сообщения: 06.11.2007 04:15
all

Раз пошли разговоры об оптимизации скриптов, то прошу совета по моему вопросу. Код приведен немаленький, и не всем он интересен, поэтому скрою под тэгом more:
[more]
Вот кусок из моего батника. Он выдирает из файлов писем *.eml (обычные текстовые файлы), создаваемых The Bat, аттачи и скармливает их утилите base64, которая приводит их в первозданый вид.


Код: echo.
echo Сохраняю решения Action1#.dau из импортированных писем.
echo Это займет некоторое время . . .

:: Определение файла настроек
set file=send.ini

:: %group_quan% задается раньше в батнике, обычно равно 7-8

for /l %%a in (1,1,%group_quan%) do (
set group_num=%%a
del /q !group_num!maillist.del 2>nul
set mail1_adress=
set mail2_adress=
set mail3_adress=
set mail4_adress=
set mail5_adress=
for /f "skip=2 delims=]=, tokens=5-9" %%a in ('find "[Group %%a team #" %file%') do (
set mail1_adress=%%a
set mail2_adress=%%b
set mail3_adress=%%c
set mail4_adress=%%d
set mail5_adress=%%e
(
if defined mail1_adress echo !mail1_adress!
if defined mail2_adress echo !mail2_adress!
if defined mail3_adress echo !mail3_adress!
if defined mail4_adress echo !mail4_adress!
if defined mail5_adress echo !mail5_adress!
)>>!group_num!maillist.del
)
for /f "skip=2 delims=] tokens=1*" %%a in ('find "[Group !group_num! mail name]" %file%') do (
set mail_name=%%b
if exist !group_num!maillist.del move /y !group_num!maillist.del "%CD%\Inbox\!mail_name!\" 2>nul
if exist "%CD%\Inbox\!mail_name!" pushd "%CD%\Inbox\!mail_name!" 2>nul

if exist *.eml (
for /f %%a in ('dir *.eml /b /a:-d') do (
for /f %%a in ('findstr /g:!group_num!maillist.del /m %%a') do (
set eml_file=
set eml_file=%%a
for /f "skip=2 tokens=1-3 delims=[]=" %%a in ('find /i /n "Action" %%a') do (
set skipmore=
set skipmore=%%a
set action=
set action=%%c
set action=!action:~1,-1!
)
echo.
chcp 866>nul
echo Сохраняю решение !action! из %group_name% !group_num!
chcp 1251>nul
set first_empty_line=
set second_empty_line=
set counter=0
for /f "tokens=1 delims=:" %%a in ('more +!skipmore! !eml_file! ^| findstr /r /v /n "."') do (
set /a counter+=1
if /i !counter! equ 1 set first_empty_line=%%a
if /i !counter! equ 2 set second_empty_line=%%a
)
set first_line=
set second_line=
set /a first_line=!skipmore!+!first_empty_line!
set /a second_line=!second_empty_line!-6
del /q !action!.del 2>nul
call :detach !first_line! !eml_file! !action!.del !second_line!
base64.exe -d !action!.del !action! 2>nul
del /q !action!.del 2>nul
)
)
)
del /q !group_num!maillist.del 2>nul
if exist "%CD%\Inbox\!mail_name!" popd
)
)
goto :next_label

:detach
set count=0
for /f "tokens=*" %%a in ('more +%~1 %~2') do (
set /a count+=1
if /i !count! lss %~4 (
echo %%a>>%~3
) else (
echo %%a | find /i "-----" >nul && goto :eof
echo %%a>>%~3
)
)
goto :eof

:next_label
echo Next Label
Автор: king_stiven
Дата сообщения: 06.11.2007 09:07
Tipulatoid
Ну например если в этой строчке
echo %%a | find /i "-----" >nul && goto :eof
мы используем не find /i а find , скорость должна повыситься. Если можно использовать findstr /c:,повыситься ещё больше. Кстати, так до конца и не понял между этими командами различий, может лучше всегда использовать findstr, чем find?
Автор: Tipulatoid
Дата сообщения: 06.11.2007 16:09
king_stiven
Это если и даст выигрыш, то мизерный. Как вы видели, у меня find обрабатывает всего только несколько строк в конце аттача. Плоха сама идея построчного переписывания в другой файл. Может, есть какая другая?
Автор: king_stiven
Дата сообщения: 06.11.2007 16:54
Tipulatoid
Вот эти скобки смущают:
(
if defined mail1_adress echo !mail1_adress!
if defined mail2_adress echo !mail2_adress!
if defined mail3_adress echo !mail3_adress!
if defined mail4_adress echo !mail4_adress!
if defined mail5_adress echo !mail5_adress!
)>>!group_num!maillist.del
Если б в выложенном примере пояснения были. что там происходит. С батом не сталкивался. и пример .eml файла.

Добавлено:
переменные %%a из

for /l %%a in (1,1,%group_quan%) do (
...
for /f "skip=2 delims=] tokens=1*" %%a in ('find "[Group !group_num! mail name]" %file%') do (
...
for /f %%a in ('dir *.eml /b /a:-d') do (
...
имеют по батнику одно значение, это правильно?

как понимать
for /f %%a in ('dir *.eml /b /a:-d') do (
for /f %%a in ('findstr /g:!group_num!maillist.del /m %%a') do (
...
??

if exist *.eml (
for /f %%a in ('dir *.eml /b /a:-d') do (
for /f %%a in ('findstr /g:!group_num!maillist.del /m %%a') do (

или я чего то не понимаю
Автор: Tipulatoid
Дата сообщения: 06.11.2007 18:24
king_stiven
[more]

Цитата:
Вот эти скобки смущают:

Как я уже сказал, это выдранный кусок из батника, потому многое непонятно. Насчет этого кода
Код: (
if defined mail1_adress echo !mail1_adress!
if defined mail2_adress echo !mail2_adress!
if defined mail3_adress echo !mail3_adress!
if defined mail4_adress echo !mail4_adress!
if defined mail5_adress echo !mail5_adress!
)>>!group_num!maillist.del
Автор: king_stiven
Дата сообщения: 06.11.2007 19:30
To all


Цитата:
Выделенные красным %%a - это просто задание первой переменной, действительной ТОЛЬКО внутри своего цикла (то, что содержится в скобках после do; если в цикл вложен другой цикл, то новая %%а работает только внутри нового подцикла), а не по всему батнику.


Неужели так бывает?
Автор: Tipulatoid
Дата сообщения: 06.11.2007 19:56
king_stiven
Может, я как-то коряво выразился. Может, то что, я хотел сказать лучше скажет такой код:

Код: @echo off
for /l %%a in (1,1,5) do (
echo Первый цикл %%a
for /l %%a in (1,1,5) do (
echo Второй цикл %%a
)
)
Автор: king_stiven
Дата сообщения: 06.11.2007 20:23
Tipulatoid
Аттачи всегда состоят из определённого числа строк?

В этом куске

Код: detach
set count=0
for /f "tokens=*" %%a in ('more +%~1 %~2') do (
set /a count+=1
if /i !count! lss %~4 (
echo %%a>>%~3
) else (
echo %%a | find /i "-----" >nul && goto :eof
echo %%a>>%~3
)
)
Автор: 01MDM
Дата сообщения: 06.11.2007 20:29
Tipulatoid
Конкректно по аттачу, но последняя строка (пустая) остается:

Код:
@echo off
setlocal enabledelayedexpansion
set skip=0
set numlines=0
for /f "delims=" %%i in ('type mail.txt ') do (
echo "%%i" | findstr "filename">nul && set skip=!numlines! || set /a numlines+=1
)

set /a skip+=5 :: 5 - кол-во строк после "filename", если во всех письмах одинаково, то гут
set /a postskip=numlines-skip-1
set count=0
for /f "skip=%skip% tokens=*" %%i in ('type mail.txt') do (
if not !count! equ %postskip% (
set /a count+=1 && if not "%%i"=="" echo %%i>>attach.txt
)
)
Автор: BlackCerber
Дата сообщения: 06.11.2007 20:47
Please помогите!!!
В общем мне нужны примеры команды для создания пользователя в определённой группе.

поясню:
Есть локальная сеть, комп в этой сети. К этому компу надо получить права админа (так чтобы мог заходить на C$, D$, E$ и т.д. ну вы меня поняли) Было уже подобное дело всё получилось но прикол в том что я не помню что за команды!!!
P.S.: Забыл пояснить... Команду можно вписать в назначенные задания (они почемуто расшаренные и команды прекрасно исполняются)

Вопрос ламерский но я нифига не помню.
ОС: WinXP

Если можно в батнике это дело сделать то это только плюс... батник есть возможность тоже подсунуть.

только естественно чтобы батник тихо себя вёл при запуске.. ну или писал ерунду какую-нибудь.
Автор: Elroir
Дата сообщения: 06.11.2007 20:55
Tipulatoid

Цитата:
Может, то что, я хотел сказать лучше скажет такой код

Интереснее так:

Код:
@echo off
for /l %%a in (1,1,5) do (
echo Первый цикл %%a
for /l %%a in (1,1,%%a) do (
echo Второй цикл %%a
)
)
Автор: king_stiven
Дата сообщения: 06.11.2007 21:03
Elroir
По моему только путаница будет, посмотри на его код
Цитата:
Подробнее...

Автор: Elroir
Дата сообщения: 06.11.2007 21:21
king_stiven
Я видел, но не стал разбирать - времени не было. А сейчас просто голова не работает.
Предыдущий мой пост не связан с основной проблемой. Я просто чуть переделал код Tipulatoid-a - пример интересного поведения уже определенной переменной во внутреннем for-e.


Добавлено:
Tipulatoid
Как я сказал выше, код я внимательно не читал. Но.. навскидку идея:
Насколько я понял, нам известна строка, с которой начинается attachment. Предположим, что это десятая строка. Тогда можно попробовать следующее:

Код: type file | more +10 /s | find /v "---" | findstr /v /r "^$">>attach.hex
Автор: king_stiven
Дата сообщения: 06.11.2007 22:01
Elroir
Блестяще! Я как раз думал как использовать символ конца строки.
Время по анологии с вышеприведённым 0,5 сек

можно даже так

Код: more +1 /s file | find /v "---" | findstr /v /r "^$">>attach.hex
Автор: Elroir
Дата сообщения: 06.11.2007 23:13
king_stiven

Цитата:
кто быстрее?)

Зависит от процессора
У меня, например, последний твой вариант бежит за 0.12 секунды, а мой - 0.19 секунды.
Автор: king_stiven
Дата сообщения: 06.11.2007 23:31
Elroir
Мерил китайскими часами.
Автор: paveltr
Дата сообщения: 07.11.2007 00:18
Нет ли у кого на примете редактора mp3 для cmd? Есть необходимость порезать большой mp3-файл (~100-150 Мб) на мелкие (2-3 Мб каждый кусок)
Автор: king_stiven
Дата сообщения: 07.11.2007 00:46
paveltr
Ты можешь нарезать любой резалкой, а потом переименовать кусочки по маске в mp3 mp3 directcut порежет в комстроке по длительности или по паузам с примерной длительностью( но настройки в комстроке недоступны). Rar порежет по разиеру, утилита split.exe из GNU utilities for Win32 тоже.

WinRAR.exe a -m0 -v6m -inul файл_выхода резаемый_файл

или

RAR.exe a -m0 -v6m -inul файл_выхода резаемый_файл

по 6 мегов порежет


Elroir

Если пустые строки не мешают

Код: more +1 /s exc_rus.txt | findstr /B /v /c:"---">>attach.hex
Автор: Tipulatoid
Дата сообщения: 07.11.2007 03:55
king_stiven

Цитата:
Аттачи всегда состоят из определённого числа строк?

нет
Elroir

Цитата:
Насколько я понял, нам известна строка, с которой начинается attachment.

king_stiven

Цитата:
Строка начала аттача определена?

Да, верно

Проверил все предложеные варианты на своем Athlon XP 2800+ на тестовом письме с примерно полумегабайтным аттачем (переписать нужно было 7511 строк)

Первый вариант king_steven (он же был и моим первым вариантом, когда начинал писать свой код)
Код: @echo off
echo %time%
for /f "skip=41 tokens=*" %%a in (00000001.eml) do (
echo %%a | find /i "-----" >nul && goto :eof
echo %%a>>2a.txt
)
echo %time%
Автор: 01MDM
Дата сообщения: 07.11.2007 08:21
Tipulatoid

Цитата:
41

А формат письма никогда не меняется?

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869

Предыдущая тема: Доступ к реестру через RegEdit?


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.