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

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Подсчёт количества файлов и отправка сообщения об этом на мэйл c помощью PowerShell (http://forum.oszone.net/showthread.php?t=293905)

Ololosh 14-01-2015 15:30 2455957

Подсчёт количества файлов и отправка сообщения об этом на мэйл c помощью PowerShell
 
День добрый господа.
PowerShell я начал изучать недавно и вот получил первое задание:
В некую папку сохраняются файлы типа xxx.pdf, xx1.pdf, xxx2_1.pdf, xxx2_2.pdf и тд.
Необходимо посчитать общее количество всех файлов в папке, причём файлы типа xxx2_1.pdf и xxx2_2.pdf - должны считаться как 1 файл. И на почту должно скидываться письмо с их количеством.

Пока я только смог осилить лишь подсчёт всех файлов и отправка этого на почту:

$a = (Get-ChildItem -Path D:\test\ -Include *.pdf -Recurse | Measure-Object -Property Length -Sum).count
Send-MailMessage -From "<xxx>" -To "<yyy>" -Subject "Сумма файлов в какой-то папке" -Body "Сумма файлов равна $a" -SmtpServer zzz

Но я не могу придумать алгоритм по которому будут считаться файлы вида xxx2_1.pdf и xxx2_2.pdf как один файл. Кто может помочь с этой задачей? желательно подробно описать что и как.

red.army@vk 14-01-2015 15:48 2455970

дак может просто не считать файлы xxx2_2 ???

Ololosh 14-01-2015 15:53 2455973

red.army@vk, файл ххх2_2 я привёл как пример, так как он является лишь частью файла ххх2 - то конешно он сам не будет считаться в общем количестве.

red.army@vk 14-01-2015 16:02 2455979

ну как то так тогда ls *.pdf -Exclude *_2.pdf

$a = ls *.pdf -Path D:\test\* -Exclude *_2.pdf -Recurse
Measure-Object -InputObject $a -Property Length -Sum
Send-MailMessage -From "<xxx>" -To "<yyy>" -Subject "Сумма файлов в какой-то папке" -Body "Сумма файлов равна $a.count" -SmtpServer zzz

кстате можно вообще без второй строчки, если интерестно только КОЛ-ВО

Код:

$a = ls *.pdf -Path D:\test\* -Exclude *_2.pdf -Recurse
Send-MailMessage -From "<xxx>" -To "<yyy>" -Subject "Сумма файлов в какой-то папке" -Body "Сумма файлов равна $a.count" -SmtpServer zzz

И для русского языка в сообщении лучше указать кодировку UTF8 в Send-MailMessage
-Encoding UTF8

Ololosh 14-01-2015 16:25 2455990

red.army@vk, это по-моему лишь выдаст все пдф без "_2"
Но нужно учитывать что файлы могут быть и "_3" и "_4" и вообще "_"любое значение"".
Кроме того, файлы могут сразу называться 123_2.pdf

red.army@vk 14-01-2015 16:32 2455996

Так и не понял, что Вы хотите) Опишите подробней
Считать нужно только *_1.pdf ?
Или все кроме *_2.pdf ?

Ololosh 14-01-2015 16:40 2456003

Нужно посчитать количество файлов в определённой папке, файлы типа ххх1_1, ххх1_2 нужно объединить, чтобы при подсчёте они числились как один файл, пример:
123.pdf
1234.pdf
1234_46.pdf
ххх1_1.pdf
ххх1_2.pdf

при подсчёте - должно получиться 3 файла

Kazun 14-01-2015 16:57 2456012

Код:

$count = @(Get-ChildItem *.pdf | Group {$_.basename.split("_")[0]}).Count

Ololosh 14-01-2015 17:07 2456018

Kazun, а можно как-то по подробней...что за действия в коде и как его применить в моём случае

Foreigner 14-01-2015 17:08 2456020

Как-то так, считает группу файлов "имя_номер" за один, если они начинаются с единицы, т.е:

123_1.txt, 123_2.txt, 123_4.txt -- группа
123_2.txt, 123_3.txt -- не группа, а отдельные файлы

Код:

$f = gci .\test *.txt

$n = @{}
switch -regex ($f.basename) {

        ".+_\d+" {
       
                [array] $n.$($_ -replace '_\d+','') += $_
       
        }
       
        default  { $c++ }

}

($n.keys).foreach({
       

        if (($n.$_[0] -replace '.+_(\d)$','$1') -eq 1) { $c++ }
        else { $c += $n.$_.count }
       
})

$c


Iska 14-01-2015 17:08 2456021

Цитата:

Цитата Ololosh
причём файлы типа xxx2_1.pdf и xxx2_2.pdf - должны считаться как 1 файл. »

По какому принципу эти (и другие) файлы должны рассматриваться, как один?

У… как я припоздал :lol:…

Ololosh 14-01-2015 17:12 2456027

Iska, видимо если название до "_*.pdf" соответствует названию другого файла до "_*.pdf" - то их можно считать за один

Foreigner,
простите меня за мою неопытность, но не могли бы подробнее описать, что делается в вашем коде и как его запустить

Iska 14-01-2015 17:22 2456035

Ololosh, да я понял уже. Пока я рассусоливал, уже спросили, ответ получили и решение на-гора выдали:
Цитата:

Цитата Kazun
Код:

$count = @(Get-ChildItem *.pdf | Group {$_.basename.split("_")[0]}).Count
»

Обратите внимание, как изящно сие выглядит (ну, когда знаешь и умеешь-то ;)).

Ololosh 14-01-2015 17:27 2456038

Iska, а не могли бы вы тогда мне объяснить, что происходит в данном ответе и как его использовать, просто мои познания пока не позволяют этого сделать.

Foreigner 14-01-2015 17:27 2456039

Ololosh, Прописываете название директории с файлами ( у меня .\test, это относительный путь) и маску файлов (например *.pdf). Если надо рекурсивно , то добавьте ключ -recurse (например $f = gci C:\test *.pdf -recurse). Скрипт выведет кол-во файлов (или групп файлов).

все остальное можно найти в справке:
Код:

help about_arrays
help about_hash_tables
help about_switch


Ololosh 14-01-2015 17:31 2456044

Foreigner,
Ответ он мне вроде выдаёт, только перед этим какую-то ещё ошибку:

Произошла ошибка при вызове метода, так как [System.Collections.Hashtable+KeyCo
llection] не содержит метод с именем "foreach".
строка:16 знак:18
+ ($n.keys).foreach <<<< ({
+ CategoryInfo : InvalidOperation: (foreach:String) [], RuntimeEx
ception
+ FullyQualifiedErrorId : MethodNotFound

3

Iska 14-01-2015 17:32 2456046

Цитата:

Цитата Ololosh
Ответ он мне вроде выдаёт, только перед этим какую-то ещё ошибку: »

Покажите тогда Ваш код.

Foreigner 14-01-2015 17:34 2456050

Ololosh, PowerShell какой версии?

замените блок с foreach на:
Код:

$n.keys | % {
       

        if (($n.$_[0] -replace '.+_(\d)$','$1') -eq 1) { $c++ }
        else { $c += $n.$_.count }
       
}


Ololosh 14-01-2015 17:35 2456053

Iska, я для примера создал txt файлы, но это сути не меняет
$f = gci D:\test\*.txt -recurse

$n = @{}
switch -regex ($f.basename) {

".+_\d+" {

[array] $n.$($_ -replace '_\d+','') += $_

}

default { $c++ }

}

($n.keys).foreach({


if (($n.$_[0] -replace '.+_(\d)$','$1') -eq 1) { $c++ }
else { $c += $n.$_.count }

})

$c

Ololosh 15-01-2015 09:57 2456284

Foreigner, версия 2.0
Прошу прощения, но скрипт оказывается не работает, а просто выдаёт числа. При каждом новом запуске скрипт показывает на +1 больше число. Но с заменой на
Цитата:

Цитата Foreigner
$n.keys | % {
if (($n.$_[0] -replace '.+_(\d)$','$1') -eq 1) { $c++ }
else { $c += $n.$_.count }
} »

ошибка действительно пропала.

Так по поводу скрипта господина Kazun-a
Цитата:

Цитата Kazun
$count = @(Get-ChildItem *.pdf | Group {$_.basename.split("_")[0]}).Count »

Спасибо, скрипт сработал..было не легко, но я понял как его использовать.
Но кто-нибудь может объяснить, что он делает более подробно?


Время: 21:10.

Время: 21:10.
© OSzone.net 2001-