Тема: CMD/BAT: Аналог bash на bat
в скрипте есть функция grep Raw_Read_Error_Rate | awk '{print $4}' которая берет из файла строки которые начинаются с Raw_Read_Error_Rate и выводит 4 столбец в этой строке. Можно ли на bat сделать такое же?
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
в скрипте есть функция grep Raw_Read_Error_Rate | awk '{print $4}' которая берет из файла строки которые начинаются с Raw_Read_Error_Rate и выводит 4 столбец в этой строке. Можно ли на bat сделать такое же?
Что такое «четвёртый столбец»? А так — да:
@echo off
setlocal enableextensions enabledelayedexpansion
set sSourceFile=0001.txt
for /f "usebackq tokens=4" %%i in (
`type "%sSourceFile%" ^| findstr.exe /r /b /c:"Raw_Read_Error_Rate"`
) do echo.%%i
endlocal
exit /b 0
4 столбец - VALUE.
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME FLAG VALUE WORST THRESH TYPE UPDATED WHEN_FAILED RAW_VALUE
1 Raw_Read_Error_Rate 0x000f 120 099 006 Pre-fail Always - 236997101
3 Spin_Up_Time 0x0003 100 100 000 Pre-fail Always - 0
4 Start_Stop_Count 0x0032 099 099 020 Old_age Always - 1152
5 Reallocated_Sector_Ct 0x0033 100 100 036 Pre-fail Always - 0
7 Seek_Error_Rate 0x000f 084 060 030 Pre-fail Always - 244136058
Вопрос более конкретный
На баше сделано так: берется файл с отчетом, см. выше пример.
Значениям ValueSmart1 и ThresholdSmart1 присваиваются соответствующие значения из отчета, данные берутся по столбцам.
ValueSmart1=$(cat /tmp/smartsda.txt | grep Raw_Read_Error_Rate | awk '{print $4}')
ThresholdSmart1=$(cat /tmp/smartsda.txt | grep Raw_Read_Error_Rate | awk '{print $6}')
if [ $ValueSmart1 -le $ThresholdSmart1 ]
then
берутся 4 и 6 столбцы и сравниваются между собой. Можно ли что-то подобное на батнике сделать?
Что-либо «подобное» — можно. Только где ж тут «строки которые начинаются с Raw_Read_Error_Rate», а?
@echo off
setlocal enableextensions enabledelayedexpansion
set sSourceFile=C:\Песочница\057\0001.txt
if exist "%sSourceFile%" (
for /f "usebackq tokens=4,6" %%i in (
`type "%sSourceFile%" ^| find.exe /i "Raw_Read_Error_Rate"`
) do (
set sValueSmart=%%i
set sThresholdSmart=%%j
)
if defined sValueSmart (
if defined sThresholdSmart (
if !sValueSmart! leq !sThresholdSmart! (
echo ValueSmart [!sValueSmart!] less or equal than ThresholdSmart [!sThresholdSmart!]
) else (
echo ValueSmart [!sValueSmart!] greater than ThresholdSmart [!sThresholdSmart!]
)
) else (
echo Can't find [ThresholdSmart] value.
exit /b 3
)
) else (
echo Can't find [ValueSmart] value.
exit /b 2
)
) else (
echo Can't find source file [%sSourceFile%].
exit /b 1
)
endlocal
exit /b 0
P.S. C bash не знаком.
Благодарю, все работает, подправил под себя для отправки писем.
И последний вопрос, если можно: можно ли здесь же сделать сравнение не по одной строке, а по нескольким: т.е. брать например еще
5 Reallocated_Sector_Ct
7 Seek_Error_Rate
и в них так же сравнивать те же столбцы?
Можно продублировать весь участок, начиная с «for /f "usebackq tokens=4,6" %%i in (…», заменив «Raw_Read_Error_Rate» на потребное. Если не то — опишите желаемое подробнее.
Если продублировать - получится не совсем то: он будет выполняться последовательно, по этому будет несколько писем.
@echo off
setlocal enableextensions enabledelayedexpansion
set sSourceFile=C:\smarta.txt
if exist "%sSourceFile%" (
for /f "usebackq tokens=4,6" %%i in (
`type "%sSourceFile%" ^| find.exe /i "Raw_Read_Error_Rate"`
) do (
set sValueSmart=%%i
set sThresholdSmart=%%j
)
if defined sValueSmart (
if defined sThresholdSmart (
if !sValueSmart! leq !sThresholdSmart! (
echo ValueSmart [!sValueSmart!] less or equal than ThresholdSmart [!sThresholdSmart!]
C:\sendemail.exe -f messages@mail -t admin@mail -u PROBLEM: SMART %COMPUTERNAME%
) else (
echo ValueSmart [!sValueSmart!] greater than ThresholdSmart [!sThresholdSmart!]
C:\sendemail.exe -f messages@mail -t admin@mail -u OK: SMART %COMPUTERNAME%
)
) else (
echo Can't find [ThresholdSmart] value.
exit /b 3
)
) else (
echo Can't find [ValueSmart] value.
exit /b 2
)
) else (
echo Can't find source file [%sSourceFile%].
exit /b 1
)
endlocal
exit /b 0
получится что если дублировать цикл проверки, то при каждом проходе будет отправляться сообщение.
Если я правильно понимаю.
А хотелось бы так: сравниваются значения из нужных строк и если какое либо условие не проходит - отправляется письмо.
Для понятия приведу пример
ValueSmart2=$(cat /tmp/smartsda.txt | grep Spin_Up_Time | awk '{print $4}')
ThresholdSmart2=$(cat /tmp/smartsda.txt | grep Spin_Up_Time | awk '{print $6}')
Opisanie2="Если VALUE стало меньше THRESH в случае Pre-fail атрибута — существует большая вероятность, что диск вылетит в ближайшие 24 часа. Spin Up Time - время раскрутки пакета дисков из состояния покоя до рабочей скорости. При расчете нормализованного значения (Value) практическое время сравнивается с некоторой эталонной величиной, установленной на заводе. Не ухудшающееся немаксимальное значение при Spin Up Retry Count Value = max (Raw равном 0) не говорит ни о чем плохом. Отличие времени от эталонного может быть вызвано рядом причин, например просадка по вольтажу блока питания."
ValueSmart3=$(cat /tmp/smartsda.txt | grep Reallocated_Sector_Ct | awk '{print $4}')
ThresholdSmart3=$(cat /tmp/smartsda.txt | grep Reallocated_Sector_Ct | awk '{print $6}')
Opisanie3="Если VALUE стало меньше THRESH в случае Pre-fail атрибута — существует большая вероятность, что диск вылетит в ближайшие 24 часа. Reallocated Sector Count - число операций переназначения секторов. SMART в современных дисках способен произвести анализ сектора на стабильность работы на лету и в случае признания его сбойным, произвести его переназначение."
ValueSmart5=$(cat /tmp/smartsda.txt | grep Spin_Retry_Count | awk '{print $4}')
ThresholdSmart5=$(cat /tmp/smartsda.txt | grep Spin_Retry_Count | awk '{print $6}')
Opisanie5="Если VALUE стало меньше THRESH в случае Pre-fail атрибута — существует большая вероятность, что диск вылетит в ближайшие 24 часа. Spin Up Retry Count - число повторных попыток раскрутки дисков до рабочей скорости, в случае если первая попытка была неудачной. Ненулевое значение Raw (соответственно немаксимальное Value) свидетельствует о проблемах в механической части накопителя."
if [ $ValueSmart1 -le $ThresholdSmart1 ]
then
cat /tmp/smartsda.txt | /usr/local/bin/email -f info@mail.in -n SMART -b -no-encoding $EMAIL -s "PROBLEM: SMART Raw_Read_Error_Rate, Value="$ValueSmart1", Threshold="$ThresholdSmart1
elif [ $ValueSmart2 -le $ThresholdSmart2 ]
then
cat /tmp/smartsda.txt | /usr/local/bin/email -f info@mail.in -n SMART -b -no-encoding $EMAIL -s "PROBLEM: SMART Spin_Up_Time, Value="$ValueSmart2", Threshold="$ThresholdSmart2
elif [ $ValueSmart3 -le $ThresholdSmart3 ]
then
cat /tmp/smartsda.txt | /usr/local/bin/email -f info@mail.in -n SMART -b -no-encoding $EMAIL -s "PROBLEM: SMART Spin_Retry_Count, Value="$ValueSmart5", Threshold="$ThresholdSmart5
else
cat /tmp/smartsda.txt | /usr/local/bin/email -f info@mail.in -n SMART -b -no-encoding $EMAIL -s "OK: SMART
fi
и если какое либо условие не проходит - отправляется письмо.
Ну, вот, как-то так (не проверялось):
@echo off
setlocal enableextensions enabledelayedexpansion
set sSourceFile=C:\Песочница\057\0001.txt
set sStrings=Raw_Read_Error_Rate Reallocated_Sector_Ct Seek_Error_Rate
if exist "%sSourceFile%" (
for %%i in (%sStrings%) do for /f "usebackq tokens=4,6" %%j in (
`type "%sSourceFile%" ^| find.exe /i "%%~i"`
) do (
set sValueSmart=%%j
set sThresholdSmart=%%k
if defined sValueSmart (
if defined sThresholdSmart (
if !sValueSmart! leq !sThresholdSmart! (
echo ValueSmart [!sValueSmart!] less or equal than ThresholdSmart [!sThresholdSmart!]
set /a bProblemFound = 1
) else (
echo ValueSmart [!sValueSmart!] greater than ThresholdSmart [!sThresholdSmart!]
)
) else (
echo Can't find [ThresholdSmart] value for [%%~i] parameter.
exit /b 3
)
) else (
echo Can't find [ValueSmart] value for [%%~i] parameter.
exit /b 2
)
)
if defined bProblemFound (
"C:\sendemail.exe" -f messages@mail -t admin@mail -u PROBLEM: SMART %COMPUTERNAME%
) else (
"C:\sendemail.exe" -f messages@mail -t admin@mail -u OK: SMART %COMPUTERNAME%
)
) else (
echo Can't find source file [%sSourceFile%].
exit /b 1
)
endlocal
exit /b 0
Ваша задача на баше изначально написана сложно.
Вот перевод на cmd/bat
@echo off
set "filename=z.txt"
for /f "tokens=4,6" %%a in ( '
find "Raw_Read_Error_Rate" ^<"%filename%
' ) do (
if %%a lss %%b echo:%%a less %%b
)
Если будете поддерживать башевский вариант может быть стоит сделать так (2 варианта):
# variant 1: финт с возвратом кода (обратите внимание на восклицательный знак в коде awk)
# 0 - значит значение поля 4 меньше значения поля 6
# 1 - наоборот
if awk '/Raw_Read_Error_Rate/ { exit ! ( $4 < $6 ); } END { exit 1; }' "$filename"
then
# variant 2: в awk вычисляем разницу, а в шелле сравниваем с нулем
diff_4_6="$( awk '/Raw_Read_Error_Rate/ { print $4 - $6; }' "$filename" )"
if [ "$diff_4_6" -lt "0" ]
then
В мире юникс не любят делать двойную работу и если что-то можно сделать в одно действие. то поступают именно так. И еще, я бы не стал закладываться на то, что во входном файле строка с подстрокой Raw_Read_Error_Rate единственная. Думаю, что башизмов в примерах нет.
Не знаю. Наверно - нет. Скорее всего - нет. Данная фраза была сказана без вкладывания смысла в данный атрибут. В тот момент я не имел ввиду искомую подстроку вообще, хотя упомянул ее явно. Согласен - фраза спорная.
Спасибо, взял вариант alexii с небольшими правками под себя.
Rumata ваш вариант может быть более логичен и правилен, но более понятный как-то удобней.
mekok
Не то чтобы правильнее. Я бы сказал - экономичнее. Хотя в данном случае - повторно прочитать файл в 10 строк - не критично. В данном случае это даже экономия на спичках.
Когда надо обработать десяток многомегабайтных лог-файлов в поисках заданной строки, то задумываешься, как сократить собственное время ожидания завершения команды.
Когда надо обработать десяток многомегабайтных лог-файлов в поисках заданной строки, то задумываешься, как сократить собственное время ожидания завершения команды.
Я уже не задумываюсь — LogParser наше всё .
logparser под юникс?
В довесок: обычно большие логи хранятся в сжатом вид, а штатных средств для работы с архивами и текстовыми файлами в виндоуз практически нет.
logparser под юникс?
Нет конечно. Под Windows.
В довесок: обычно большие логи хранятся в сжатом вид,
Например? Не припоминаю такого.
а штатных средств для работы с архивами
Угу. Нет. Потому как см. выше: я не припоминаю таких логов.
текстовыми файлами в виндоуз практически нет.
WSH. PoSH.
WSH. PoSH.
Штатным PowerShell стал начиная с семерки, WSH - более "штатный".
Штатным PowerShell стал начиная с семерки,
Точнее — идущим в комплекте поставки.
Точнее — идущим в комплекте поставки.
Если принципально, то - да, по сути - не столь важно.
greg zakharov, сейчас сверился — таки да, Вы правы: «штатно» — именно оно, «идущее по штату», «состоящее в штатном расписании» и т.п.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться