Скрипт для сравнения размера файла одного файла - PullRequest
1 голос
/ 31 января 2020

Я пытаюсь написать скрипт, который сообщит мне, если размер файла больше, чем число, ниже приведен скрипт, который я написал, но он показывает 1999 год, хотя я знаю, что размер файла больше, чем число.

@echo off
setlocal enabledelayedexpansion

for /f "delims=" %%a in (' powershell -c "(Get-ChildItem -Recurse "C:\XSTOREDB\xstore_data.mdf" | Measure-Object -Property Length -Sum).Sum" ') do set "foldsize=%%a"

if "!foldsize!" GTR "6000000000" (
    exit /B 0
) else (
    exit /B 1999
)
endlocal

Ответы [ 3 ]

1 голос
/ 01 февраля 2020

Я почти уверен, что у вас 2 проблемы. Первая проблема заключается в том, что вы делаете алфавитное сравнение. Таким образом, "7" будет считаться GTR "6000000000".

Ваша вторая проблема заключается в том, что число c операций в cmd ограничено 32-битными целыми числами. Максимальное число, которое вы можете использовать, составляет 2 ^ 31 - 1, то есть 2147483647, что уже меньше, чем число, которое вас интересует.

Типичный обходной путь здесь - это сравнить "важные" части строка или усечение N младших значащих цифр.

Вот пример quick . Может содержать проблемы / ошибки в реализации. Я сделал echo exit /b, чтобы скрипт запускался, и вы могли видеть результаты вместо exit /b.

@echo off
setlocal enabledelayedexpansion

rem first we will inspect the 10th and 11th digits from the right
set foldsize=7000000010

rem If there is any number in the 11th spot, then it must be greater
if not "!foldsize:~0,-10!"=="" (
   rem the number is at least 10000000000 which is greater so we exit
   echo exit /B 0
)

rem check if the 10th digit is 6 or greater
rem add a zero to avoid issues with an undefined variable
set smallfoldsize=!foldsize:~0,-9!
if !smallfoldsize!0 GTR 50 (
   rem technically the number is now greater or equal to 6000000000
   rem I will leave it up to you if you really need it to be greater than
   echo exit /B 0
   ) else (
      rem it is smaller
      echo exit /B 1999
)



rem an alternative is to discard the N least significant digits
rem I am stripping the last 7 digits and then adding a zero to avoid
rem an undefined variable
set smallfoldsize=!foldsize:~0,-7!0
if !smallfoldsize! GEQ 6000 (
   echo exit /B 0
   ) else (
      echo exit /B 1999
)
rem again, this is actual greater or equal.  If you
rem need greater than, you have to look at the less
rem significant digits when smallfoldsize = 6000
0 голосов
/ 04 февраля 2020

Несмотря на то, что ваше тело вопроса, текст и заголовок не соответствуют предоставленному вами коду, я не вижу необходимости в для этой задачи.

На основании вашего основного текста вопроса и заголовка , чтобы выйти с уровнем ошибки 0, если файл C:\XSTOREDB\xstore_data.mdf больше 6GB:

@"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "If(Test-Path -L "C:\XSTOREDB\xstore_data.mdf"){(GI -L "C:\XSTOREDB\xstore_data.mdf").Length -GT 6GB}" 2>NUL|"%__AppDir__%find.exe" "T">NUL&&(Exit /B 0)||Exit /B 1999

Исходя из кода вашего вопроса , для выхода с уровнем ошибки 0, если каталог C:\XSTOREDB содержит более 6GB:

@"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "If(Test-Path -L "C:\XSTOREDB"){(GCI "C:\XSTOREDB" -Rec|Measure Length -Su -EA Stop).Sum -GT 6GB}" 2>NUL|"%__AppDir__%find.exe" "T">NUL&&(Exit /B 0)||Exit /B 1999
0 голосов
/ 01 февраля 2020

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

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

  • Заставить PowerShell возвращать значение в мегабайты (МиБ), а не байты.

  • Это должно вернуть достаточно маленькое число, которое вы можете сравнить (численно) с cmd 's * Оператор 1020 *.

@echo off
setlocal enabledelayedexpansion

for /f "delims=" %%a in ('
powershell -noprofile -c ^
  "[math]::Ceiling((Get-ChildItem -File -Recurse \"C:\XSTOREDB\xstore_data.mdf\" | Measure-Object -Property Length -Sum).Sum / 1mb)"
') do set "foldsize=%%a"

:: # 6000000000 bytes is ca. 5722 MB
if !foldsize! GTR 5722 (
    exit /B 0
) else (
    exit /B 1999
)

Обратите внимание, как команда PowerShell делит результат на 1mb (1 МБ (мегабайт) = 2 ^ 20 = 1,048,576 байт), а затем округляет это вверх через [math]::Ceiling()

Также обратите внимание, как встроенный " символов. были экранированы как \", чтобы гарантировать, что PowerShell их видит.

Наконец, обратите внимание, как в качестве небольшой оптимизации -File был передан командлету Get-ChildItem для пропуска каталогов (сами по себе, а не их файлы), учитывая, что сами каталоги не имеют Length свойства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...