Войти

Показать полную графическую версию : [решено] Подсчёт количества файлов и отправка сообщения об этом на мэйл c помощью PowerShell


Ololosh
14-01-2015, 15:30
День добрый господа.
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
дак может просто не считать файлы xxx2_2 ???

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

red.army@vk
14-01-2015, 16:02
ну как то так тогда 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
red.army@vk, это по-моему лишь выдаст все пдф без "_2"
Но нужно учитывать что файлы могут быть и "_3" и "_4" и вообще "_"любое значение"".
Кроме того, файлы могут сразу называться 123_2.pdf

red.army@vk
14-01-2015, 16:32
Так и не понял, что Вы хотите) Опишите подробней
Считать нужно только *_1.pdf ?
Или все кроме *_2.pdf ?

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

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

Kazun
14-01-2015, 16:57
$count = @(Get-ChildItem *.pdf | Group {$_.basename.split("_")[0]}).Count

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

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

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
причём файлы типа xxx2_1.pdf и xxx2_2.pdf - должны считаться как 1 файл. »
По какому принципу эти (и другие) файлы должны рассматриваться, как один?

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

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

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

Iska
14-01-2015, 17:22
Ololosh, да я понял уже. Пока я рассусоливал, уже спросили, ответ получили и решение на-гора выдали:
$count = @(Get-ChildItem *.pdf | Group {$_.basename.split("_")[0]}).Count »

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

Ololosh
14-01-2015, 17:27
Iska, а не могли бы вы тогда мне объяснить, что происходит в данном ответе и как его использовать, просто мои познания пока не позволяют этого сделать.

Foreigner
14-01-2015, 17:27
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
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
Ответ он мне вроде выдаёт, только перед этим какую-то ещё ошибку: »
Покажите тогда Ваш код.

Foreigner
14-01-2015, 17:34
Ololosh, PowerShell какой версии?

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

$n.keys | % {


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

}

Ololosh
14-01-2015, 17:35
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
Foreigner, версия 2.0
Прошу прощения, но скрипт оказывается не работает, а просто выдаёт числа. При каждом новом запуске скрипт показывает на +1 больше число. Но с заменой на $n.keys | % {
if (($n.$_[0] -replace '.+_(\d)$','$1') -eq 1) { $c++ }
else { $c += $n.$_.count }
} » ошибка действительно пропала.

Так по поводу скрипта господина Kazun-a $count = @(Get-ChildItem *.pdf | Group {$_.basename.split("_")[0]}).Count » Спасибо, скрипт сработал..было не легко, но я понял как его использовать.
Но кто-нибудь может объяснить, что он делает более подробно?




© OSzone.net 2001-2012