Показать полную графическую версию : [решено] Подсчёт количества файлов и отправка сообщения об этом на мэйл 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
дак может просто не считать файлы xxx2_2 ???
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
red.army@vk, это по-моему лишь выдаст все пдф без "_2"
Но нужно учитывать что файлы могут быть и "_3" и "_4" и вообще "_"любое значение"".
Кроме того, файлы могут сразу называться 123_2.pdf
red.army@vk
14-01-2015, 16:32
Так и не понял, что Вы хотите) Опишите подробней
Считать нужно только *_1.pdf ?
Или все кроме *_2.pdf ?
Нужно посчитать количество файлов в определённой папке, файлы типа ххх1_1, ххх1_2 нужно объединить, чтобы при подсчёте они числились как один файл, пример:
123.pdf
1234.pdf
1234_46.pdf
ххх1_1.pdf
ххх1_2.pdf
при подсчёте - должно получиться 3 файла
$count = @(Get-ChildItem *.pdf | Group {$_.basename.split("_")[0]}).Count
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
причём файлы типа xxx2_1.pdf и xxx2_2.pdf - должны считаться как 1 файл. »
По какому принципу эти (и другие) файлы должны рассматриваться, как один?
У… как я припоздал :lol:…
Iska, видимо если название до "_*.pdf" соответствует названию другого файла до "_*.pdf" - то их можно считать за один
Foreigner,
простите меня за мою неопытность, но не могли бы подробнее описать, что делается в вашем коде и как его запустить
Ololosh, да я понял уже. Пока я рассусоливал, уже спросили, ответ получили и решение на-гора выдали:
$count = @(Get-ChildItem *.pdf | Group {$_.basename.split("_")[0]}).Count »
Обратите внимание, как изящно сие выглядит (ну, когда знаешь и умеешь-то ;)).
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
Foreigner,
Ответ он мне вроде выдаёт, только перед этим какую-то ещё ошибку:
Произошла ошибка при вызове метода, так как [System.Collections.Hashtable+KeyCo
llection] не содержит метод с именем "foreach".
строка:16 знак:18
+ ($n.keys).foreach <<<< ({
+ CategoryInfo : InvalidOperation: (foreach:String) [], RuntimeEx
ception
+ FullyQualifiedErrorId : MethodNotFound
3
Ответ он мне вроде выдаёт, только перед этим какую-то ещё ошибку: »
Покажите тогда Ваш код.
Foreigner
14-01-2015, 17:34
Ololosh, PowerShell какой версии?
замените блок с foreach на:
$n.keys | % {
if (($n.$_[0] -replace '.+_(\d)$','$1') -eq 1) { $c++ }
else { $c += $n.$_.count }
}
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
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
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.