2015-06-03 6 views
4

Я проверяю дату, измененную в файле. Я хотел бы проверить, был ли файл изменен после /d -3. Согласно docs, это проверит, был ли файл изменен до этой даты. Мне нужно проверить, был ли файл изменен после этой даты. В документах также указано, что я могу указать дату. Я мог бы сделать это таким образом, хотя было бы немного сложнее создать дату для проверки, против которой я бы предпочел избежать, если это возможно. Как я могу это сделать?Проверьте, был ли файл изменен после xx дней в прошлом

forfiles /m Item_Lookup2.csv /d -3 >nul 2>nul && (
    echo - updated 

    goto :PROCESS_FILE 
) || (

    echo - out of date 
    set outdated="true" 

    goto :CHECK_ERRORS 
) 

Я нашел in this answer

+0

Прочитайте документацию еще раз, в частности, '/ D date' раздел. – SomethingDark

+1

@SomethingDark Мне нужно, чтобы это числовое значение, а не конкретная дата. Я надеялся на более простой способ. – pcnate

+0

Возможный дубликат [FORFILES date -after- (date calc в cmd-файле)] (http://stackoverflow.com/questions/19296588/forfiles-date-after-date-calc-in-cmd-file) – aschipfl

ответ

4

Вы находитесь на правильном пути, но forfiles /d -n тестов для файлов модифицированы п дней или ранее, не позднее. Что вам нужно сделать, это поменять свои блоки кода && и ||, и, возможно, указать 4 дня вместо 3.

Если матч, то это 4 дня и старше и классифицируется как устаревший. Если нет совпадения, он обновляется за последние 3 дня.

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

forfiles /d -4 /m "Item_Lookup2.csv" >NUL 2>NUL && (
    echo - out of date 
    set outdated="true" 
    goto :CHECK_ERRORS 
) || (
    echo - updated 
    goto :PROCESS_FILE 
) 

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

powershell "(gi Item_Lookup2.csv).LastWriteTime='6/1/2015 09:30:00 AM'" 

... установит последнюю измененную временную метку Item_Lookup2.csv до 1 июня в 9:30. Солить по вкусу.

+0

Вау - такое простое и очевидное решение, как только я это вижу. Но я готов поспорить, что я один из многих, кто никогда бы не подумал об этом решении. – dbenham

+0

Спасибо! Конечно, если файл вообще не существует, это приведет к ложному срабатыванию. Дополнительная опция 'if not exist 'Item_Lookup2.csv' 'должна быть добавлена ​​перед линией' forfiles', чтобы предотвратить это. – rojo

+0

Проверьте мое [решение ROBOCOPY] (http://stackoverflow.com/a/30634954/1012053) - также как эффективные, но несколько иные правила вычисления возраста. Ни одно из решений не лучше, это зависит от того, какие правила вы хотите использовать. – dbenham

1

Фильтрация файлов по разным моментам времени не так легко с чистой партией, поэтому я попытался создать инструмент для общего пользования - FileTimeFilterJS.bat (вероятно, далек от совершенства) .Try с :

call FileTimeFilterJS.bat "." -filetime modified -direction after -dd -3 
+0

Похож для использования этого я должен иметь библиотеку, сохраненную в 'E: \ JScript \ '? – pcnate

+0

@pcnate - НЕТ! он использует встроенный wsh/jscript. 'E: \ JScript \ 'является просто аргументом командной строки для cscript.exe и означает использование механизма jscript. – npocmaka

+0

@pcnate - больше информации здесь: http://www.dostips.com/forum/viewtopic.php?p=33963 – npocmaka

0

forfiles /D +n, по-видимому, ищет файлы со временными отметками в будущем. В качестве альтернативы, используйте этот скрипт Powershell, чтобы начать с:

## usage: ff.ps1 [-age n] [-mask *.*] 
## find files newer than n days 
## with filenames matching mask 

Param (
    [float]$age = 0, 
    [string]$mask = '*.*' 
) 

$from = $(get-date).addDays(-$age) 
GCI -path '.' -filter $mask -recurse -force | Where {$_.attributes -ne "Directory"-and $_.lastwritetime -gt $from } | ForEach { write-host $_.lastwritetime ' ' $_.fullname } 

Это довольно просто, вы можете указать максимальный возраст (-Возраст п) и/или FileMask (-mask * .csv). Результат - это отметка времени + полное имя файла, которое можно легко изменить. Посмотрите на расчет даты и сравните его с кошмаром, необходимым для партии DOS.

2

Мне очень нравится rojo's answer - так просто. Мне интересно, что он игнорирует компонент времени при вычислении возраста. Таким образом, реальный возраст 1 секунды может быть рассчитан как один день, если текущее время составляет полночь, а последний измененный штамп времени - 23:59:59 с предыдущего дня. Это может быть или не быть поведением, которое вы хотите.

У меня есть другое решение, основанное на ROBOCOPY, которое использует полную метку времени при вычислении возраста файла. Поэтому, если вы укажете максимальный возраст 3 дня, тогда он ищет файлы, которые были созданы или изменены за последние 72 часа.

Одна хорошая вещь о ROBOCOPY - это позволяет указать минимальный возраст и/или максимальный возраст.

returned ERRORLEVEL is complicated, что делает его неудобным для толкования. Вместо использования ERRORLEVEL я проверяю, указывает ли команда указанный файл. Я использую цикл FOR/F, который вызывает ошибку, если файл не указан. Команда BREAK - это просто команда, которая всегда преуспевает и не производит вывод, если файл был указан.

lots of ROBOCOPY options Есть, многие из которых необходимы для этого приложения :-)

(for /f %%A in (
    'robocopy . "%temp%" "Item_Lookup2.csv" /maxage:3 /is /it /xx /l /ndl /njh /njs' 
) do break) && (
    echo - updated 
    goto :PROCESS_FILE 
) || (
    echo - out of date 
    set outdated="true" 
    goto :CHECK_ERRORS 
) 
+0

Интересная идея! Мне придется попробовать это завтра, когда я нахожусь в Windows. Что я должен ожидать в '%% A'? – pcnate

+0

В нем перечислены классы ROBOCOPY (например, 'new' или' same'), размер файла и имя файла (с помощью пути). Вы можете добавить опции '/ NC' и'/NS', чтобы исключить класс и размер из вывода. – dbenham

+0

@pcnate. Вы также можете добавить параметр '/ TS', чтобы получить последнюю измененную метку времени. Я считаю, что формат всегда будет «YYYY/MM/SS hh: mm: ss' в 24-часовом формате, независимо от языка. – dbenham