Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Сравнение файла с оригиналом, создание отчета (http://forum.oszone.net/showthread.php?t=243440)

tarasov.evgeny 26-09-2012 17:25 1995197

Сравнение файла с оригиналом, создание отчета
 
Добрый день,

Есть папка, в которую люди выкладывают файлы.
Необходимо проверить все ли люди выложи файлы, если нет - записть в отчет - забыли.txt
Затем все файлы проверяются на соответствие определенным атрибутам(все атрибуты закодированы в имени файла), если всё верно - файлы перемещаются в папку с именем сегодняшней даты
Если атрибуты файлов не верные - запись в отчет - неверно.txt
Как планируется проверять все ли люди выложили файлы в папку.
Есть файл - сотрудники.txt вот такого вида:
Код:

33-1:Отдел1:Иванов:555
22:Отдел2:Петров:333

Файлы, которые выкладывают люди имеет имя:sr_33-1_20120926.rar.enc
Надо создать проверку одного массива данных
Код:

get-content .\сотрудники.txt -replace ":.*",""
другому массиву - массиву файлов:
Код:

$files = (get-childitem).Basename
В случае если совпадение есть - то выполнять проверку дальше
В случае если совпадения нет формировать отчет забыли.txt или ошибки.txt
Отчеты такого вида:
Код:

33-1  Отдел1  Иванов  555  Ошибка
22    Отдел2  Петров  333  Ошибка

Под ошибкой понимается тип ошибки - отсутствие атрибута
Для отчета забыли отчет:
Код:

33-1  Отдел1  Иванов  555
22    Отдел2  Петров  333

Создал распихивание файлов по папкам с датой в папки - правильные и не правильные.
Не могу создать отчеты, потому что не понятно как сравнить два массива.
Делаю так.
Код:

cls
$BASE = Get-Content сотрудники.txt
$BASEName = $BASE -replace ":.*",""
cd y:\TableReports
ForEach ($a in Get-ChildItem)
        {
        $b=0
        if (($a.BaseName -replace "^S_","" -replace "_.*","") -like $BASEName[$b])
                {
                'Move-item $a.Basename'
                }
        else
                {
                "Write to log-file"
                }
        $b=$b+1
        }

Вот постоянно выдает, что не верно (то есть выполняет команду else)
Хотя одно значение должно совпадать точно
А если просто из строки выполнить
Код:

($a[1].BaseName -replace "^S_","" -replace "_.*","") -like $BASEName[$b]
Говорит True - То есть должен был бы выполнить условие до else - или другими словами одно совпадение найдено (правда здесь конкретная проверка - одно значение с другим.
Кстати только что понял, что я ожидал ответ от одиночной команды вида:
33-1 (я ведь написал -like а не -contains)
а он выдает True или False

Kazun 26-09-2012 17:42 1995211

Такого формата имя:sr_33-1_20120926.rar.enc файл не может быть.

Файл должен быть в кодировке Unicode
Код:

$base = Import-Csv сотрудники.txt -Delimiter ":" -Header "O","T",TH","F"
$files = Get-ChildItem D:\ | Where {!$_.PsIsContainer} | Select-Object -Expand FullName

foreach($name in $base)
{
        $find = $files -match $name.th
        if($find)
        {
                'Move-item $find'
        }
        else
        {
                'Write to log-file'
        }

}

tarasov.evgeny 27-09-2012 18:08 1995702

Благодарю за помощь.
Теперь не могу скопировать данные.
Код:

cls
cd y:\
$base = Import-Csv DATA.txt -Delimiter ":" -Header "N","Отдел","Контактный номер"
$files = Get-ChildItem Y:\TableReports | Where {!$_.PsIsContainer -and $_.Name -match ".enc$"} | Select-Object -Expand FullName
$DayFolder = New-item -Path Y:\week -name "$(Get-Date -uformat '%Y%m%d')" -type directory
$DayFolder2 = New-item -Path Y:\markdelete -name "$(Get-Date -uformat '%Y%m%d')" -type directory
cd Y:\TableReports
foreach($name in $base)
{
        $findFile = $files -match $name.N
        if($findFile)
        {
        Write-Host "Файл прислали"
        $findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"
                if($findAtr)
                {
                Write-Host "Атрибуты верны"
                Copy-Item -Path $findAtr -Destination $DayFolder.FullName
                }
                else
                {
                Write-Host "Атрибуты НЕ верны"
                $name.N
                Copy-Item -Path $findAtr -Destination $DayFolder2.FullName
                }
        }
        else
        {
        Write-Host "Файл НЕ прислали"
        }
}

В базе DATA.txt содержится список контактов. Начинается с номера. Есть номера вида: 53-1
Вот на них и ругается.
Код:

...
Атрибуты НЕ верны
33-1
Copy-Item : Не удается привязать аргумент к параметру "Path", так как он представляет собой пустой массив.
C:\Dropbox\VFTP_подписиЧУЖОЙ.ps1:24 знак:18
+        Copy-Item -Path <<<<  $findAtr -Destination $DayFolder2.FullName
    + CategoryInfo          : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyArrayNotAllowed,Microsoft.PowerShell.Commands.
  CopyItemCommand
 
Файл прислали
...

Я так понимаю, что вот эта конструкция:
Код:

$findFile = $files -match $name.N
        if($findFile)
{}
else
{}

В случае отрицательного значение (переход в else) в $findfile = ничего не возвращает. Как быть?

Kazun 27-09-2012 18:28 1995711

1) Зачем в скрипте команды?
cd y:\
cd Y:\TableReports

2) $findAtr = $findFile -match "rar.sig.enc$" -cmatch "S" - Какие тут тестируются атрибуты?

3) Copy-Item -Path $findAtr должно быть Copy-Item -Path $findFile

tarasov.evgeny 28-09-2012 12:15 1996040

1.
cd y:\ так как в команде не было полного пути до файла. указываю диск (исправил)
cd y:\tablereports - не могу объяснить :) - удалил

2. Атрибуты - не в привычном смысле слова. То есть это не атрибуты файловый системы (архивный, скрытый, acl, что там ещё...) - эти атрибуты закодированы в имени файла.
$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S" - мне нужны файлы, которые оканчиваются на rar.sig.enc и в имени содержат большую букву S.

3. Исправил работает.

Вот такой отчет получился.
Код:

Write-Host "Файл НЕ прислали"
        $name | Out-File не_прислали.txt -Append
        $report = get-content не_прислали.txt
        $encoding = [System.Text.Encoding]::UTF8
        $body = $report | Where-Object {$_ -ne "" -and $_ -match "[0-9]"}
        Send-MailMessage -encoding $encoding -From ftp@company.ru -To my@company.ru -Subject "Отчет об S-файлах. Не отправили:" -Body $body -SmtpServer mail.company.ru

В результате имеем:
HTML код:

22                                    Number1Номер                          1                                   
22-1                                  Number1Номер                          1                                   
44-1                                  Number2Номер3                        222-333                             
52                                    NUMBER5                              555                                 
53-1                                  Number2                              22223333444

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

cls
$base = Import-Csv y:\data.txt -Delimiter ":" -Header "N","Отдел","Контактный номер"
$files = Get-ChildItem y:\TableReports | Where {!$_.PsIsContainer -and $_.Name -match ".enc$"} | Select-Object -Expand FullName
$DayFolder = New-item -Path y:\TableReports\week -name "$(Get-Date -uformat '%Y%m%d')" -type directory
$DayFolder2 = New-item -Path y:\TableReports\markdelete -name "$(Get-Date -uformat '%Y%m%d')" -type directory
foreach($name in $base)
{
        $findFile = $files -match $name.N
        if($findFile)
        {
        Write-Host "Файл прислали"
        $name.N
        $findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"
                if($findAtr)
                {
                Write-Host "Атрибуты верны"
                $name.N
                Copy-Item -Path $findFile -Destination $DayFolder.FullName
                }
                else
                {
                Write-Host "Атрибуты НЕ верны"
                $name.N
                Copy-Item -Path $findFile -Destination $DayFolder2.FullName
                }
        }
        else
        {
        Write-Host "Файл НЕ прислали"
        $name | Out-File не_прислали.txt -Append
        $report = get-content не_прислали.txt
        $encoding = [System.Text.Encoding]::UTF8
        $body = $report | Where-Object {$_ -ne "" -and $_ -match "[0-9]"}
        Send-MailMessage -encoding $encoding -From vftp@company.ru -To my@company.ru -Subject "Отчет об S-файлах. Не отправили:" -Body $body -SmtpServer mail.company.ru
        }
}


Kazun 28-09-2012 12:32 1996055

$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S" - Попробуйте узнать результат выполнения,может отработать только в случае массива,что врятли,для скалярного значения всегда выражение будет FALSE.


Добавить перед foreach переменную notfound:


Код:

$notfound = @()
foreach($name in $base)
{
        $findFile = $files -match $name.N
        if($findFile)
        {
        Write-Host "Файл прислали $($name.N)"
        $name.N
        $findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"
                if($findAtr)
                {
                Write-Host "Атрибуты верны"
                $name.N
                Copy-Item -Path $findFile -Destination $DayFolder.FullName
                }
                else
                {
                Write-Host "Атрибуты НЕ верны"
                $name.N
                Copy-Item -Path $findFile -Destination $DayFolder2.FullName
                }
        }
        else
        {
                $notfound += $name
                Write-Host "Файл не прислали $($name.N)"
        }
}

if($notfound)
{
        $body = $notfound | Format-Table -auto | Out-String
        Send-MailMessage -encoding ([System.Text.Encoding]::UTF8) -From vftp@company.ru -To my@company.ru -Subject "Отчет об S-файлах. Не отправили:" -Body $body -SmtpServer mail.company.ru
}


tarasov.evgeny 02-10-2012 16:25 1998405

Не сколько видоизменил ТЗ.
Один скрипт будет работать как служба.
Служба:
Код:

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = 'C:\FTP'
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $false
$watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite -bor [System.IO.NotifyFilters]::FileName
 
while($TRUE){
 $result = $watcher.WaitForChanged([System.IO.WatcherChangeTypes]::All, 1000);
 if($result.TimedOut){
 continue;
}
C:\Scripts\S-files\S-FilesCheck.ps1
}

В случае обнаружения изменений в папке - скрипт будет пинать второй.
Второй скрипт проверяет:
есть ли папка за сегодняшнее число. Если нет, то создает и проверяет файлы на вшивость.
Если файл нормальный, то копируется в папку - нормальные
Если файл не нормальный. копируется в папку не правильные и пишется сообщение на почту, что файл не верный (отображаются контакты накосячивших)
Второй - проверка файлов:
cls
Код:

$Checkfolder = Test-Path -Path "c:\Reports\$(Get-Date -uformat '%Y%m%d')"
if($checkfolder -eq $False)
        {       
        New-item -Path "C:\Reports\" -name "$(Get-Date -uformat '%Y%m%d')" -type directory
        $DayOK = New-item -Path "C:\Reports\$(Get-Date -uformat '%Y%m%d')" -name 'OK' -type directory
        $DayNoOK = New-item -Path "C:\Reports\$(Get-Date -uformat '%Y%m%d')" -name 'NoOK' -type directory
        Write-Host "Create folder DATA, NoOK, OK"
        }
$base = Import-Csv C:\Scripts\S-files\data.txt -Delimiter ":" -Header "N","Отдел","Контактное лицо", "Телефон"
$files = Get-ChildItem c:\ftp | Where {!$_.PsIsContainer -and $_.Name -match ".enc$"} | Select-Object -Expand FullName
foreach($name in $base)
{
        $findFile = $files -match $name.N
        if($findFile)
        {
        Write-Host "Файл прислали $name.N"
        $findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"
                if($findAtr)
                {
                Write-Host "Атрибуты верны"
#                Move-Item -Path $($findFile) -Destination $DayOK.FullName
                }
                else
                {
                Write-Host "Атрибуты НЕ верны"
#                Copy-Item -Path $($findFile) -Destination $DayNoOK.FullName
                }
        }
}

Третий скрипт в одно время формирует список тех, кто не прислал файл вообще и отправляет отчет на почту

Второй вообще не отрабатывает. Причем как с @(notfound) так и без неё (я не до конца понял, как это работает).
А то что отрабатывает вообще не понятно как отрабатывает
Скажем по факту два файла. Один нормальный, второй нет.
А скрипт говорит, что:
- все атрибуты верны
- что прислали файл не два человек, а скажем 5

Kazun 02-10-2012 16:46 1998413

Я уже третий раз спрашиваю про условие "$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"" - ЧТО ЭТО?

tarasov.evgeny 02-10-2012 16:52 1998415

Извиняюсь. Я вроде как ответил.
$findFile = $files -match $name.N
if($findFile)
Это первая проверка - ищем файл. Если нашли, то:
$findAtr = $findFile -match "rar.sig.enc$" -cmatch "S"
весь путь, который нам возвращает вот эта команда
$files = Get-ChildItem c:\ftp | Where {!$_.PsIsContainer -and $_.Name -match ".enc$"} | Select-Object -Expand FullName
Например,
C:\ftp\S_11_20121002.rar.sig.enc

проверяем на содержание - есть ли в строчке - S, rar.sig.enc
$files.GetType().Name - возвращает string.
$findatr - возвращает boolean
Поэтому путь не подставлялся (boolean никак не подставишь), а отчет выдает больше вхождения - потому что files по символам разбирается.
Но как сделать правильно?

Нужно вот это изменить:
"$findAtr = $files -match "rar.sig.enc$" -cmatch "S"

Kazun 02-10-2012 16:57 1998419

Тогда еще разок(в 6 посте я это описал,но читать конечно же не обязательно):
PS Z:\> "C:\ftp\S_11_20121002.rar.sig.enc" -match "rar.sig.enc$" -cmatch "S"
False
PS Z:\> "C:\ftp\S_11_20121002.rar.sig.enc" -match "rar.sig.enc$"
True

$findAtr = $findFile -match "\\S.+\.rar\.sig\.enc$"


Время: 01:43.

Время: 01:43.
© OSzone.net 2001-