Показать полную графическую версию : Поиск с созданием списка файлов с последующим их копированием.
rengaboy
28-05-2018, 23:38
Доброго времени суток.
Есть много групп файлов в разных папках. Группа состоит из файлов с расширениями jpg, txt, xml. В xml файле есть параметр, по которому файлы надо сортировать в отдельную папку - "<ttemp>nn". "nn" - целое число, если оно меньше 50, файл не трогаем, если больше, копируем его в папку "alert".
На данный момент все решено следующей связкой:
Multiple search and replace - В поиске задаем (\<ttemp\>)([1-9]\d{2,}|[4-9][9-9]), сохраняем результаты в файл result.txt, соответственно в списке только xml файлы с полным путем
Далее в Notepad ++ ищем по файлу "^(.*)(\.xml)" и заменяем на "\1(\.jpg)\r\1(\.txt)\r\1(\.xml)", получаем список всех нужных файлов
Далее запускаем скрипт на PS, который уже эти файлы копирует в нужную папку.
$read = Get-Content .\result.txt
$conv = Out-String -InputObject $read -Stream
ForEach ($Str in $conv){
IF ( Get-ChildItem "$str" | Where-Object { $_.exists -eq "true"})
{Copy-Item "$Str" -destination "H:\alert\"}
else {"Файла не существует"}}
Собственно понимаю, что можно первые два шага тоже перенести в PowerShell, но сам справиться не могу.
Группа состоит из файлов с расширениями jpg, txt, xml »
Это как понять? Группа состоит из трёх одноимённых файлов с разными расширениями, так? Всегда наличествуют все три файла, обязательно?
В xml файле есть параметр, по которому файлы надо сортировать в отдельную папку - "<temp>nn". »
Покажите образцы xml файлов, упакованных в архив. И желательно вместе с одноимёнными «одногруппниками» jpg и txt.
файл не трогаем, …, копируем его »
Какой файл не трогаем или копируем, xml? При чём тут тогда упомянутые выше его «одногруппники», с ними что-нибудь делаем?
в папку "alert". »
Где она находится, эта папка?
rengaboy
29-05-2018, 00:41
Это как понять? Группа состоит из трёх одноимённых файлов с разными расширениями, так? Всегда наличествуют все три файла, обязательно? »
Именно так. Имена файлов рандомные, наподобие d530f6c2d0a9b319809e8c022b69bccf.xml Всегда наличествуют три файла,обязательно.
Покажите образцы xml файлов, упакованных в архив. И желательно вместе с одноимёнными «одногруппниками» jpg и txt. »
К сожалению показать файлы не могу, так как объект режимный.
jpg- фото с камеры
txt- состояние клапанов и вентилей в текстовом формате
sensor ........1-18
sensor ........2-50
sensor ........3-28
bleeder .......1-0
bleeder .......2-0
valve ..........1-0
valve ..........2-1
Состав xml примерно такой:
<?xml version="1.0" encoding="windows-1251"?>
<report>
<info>
<nImagePresent>1</nImagePresent>
<nSize>.......</nSize>
<nImageWidth>....</nImageWidth>
<nImageHeight>....</nImageHeight>
<tChannel>....</tChannel>
<tTemp>50</tTemp>
<tSensorName>...........</tSensorName>
<tLocationCode>..............</tLocationCode>
<tLatitude>...............</tLatitude>
<tLongitude>.............</tLongitude>
<nDatetime>..............</nDatetime>
<nTZOffset>+3.00</nTZOffset>
Какой файл не трогаем или копируем, xml? При чём тут тогда упомянутые выше его «одногруппники», с ними что-нибудь делаем? »
Не трогаем файлы, если температура меньше, если больше, копируем все три файла в отдельную папку.
Где она находится, эта папка? »
На том же диске, где находится основной архив.
Состав xml примерно такой: »
Примерно не годится, нужно точно. Содержимое внутри (заменённое точками) по сути не важно, важна структура файла.
На том же диске, где находится основной архив. »
Где именно? В корневом каталоге раздела, в текущем каталоге, в содержащем скрипт каталоге, в исходном каталоге? Она уже существует или её, возможно, потребуется создавать, если отсутствует?
rengaboy
29-05-2018, 01:29
Примерно не годится, нужно точно. Содержимое внутри (заменённое точками) по сути не важно, важна структура файла. »
Так это структура и есть. Там еще 15 полей, и в конце закрывашки </info></report>. Температуру мы смотрим в поле <tTemp>50</tTemp>
Где именно? В корневом каталоге раздела, в текущем каталоге, в содержащем скрипт каталоге, в исходном каталоге? Она уже существует или её, возможно, потребуется создавать, если отсутствует? »
Всё равно. Она потом копируется на флешку. Допустим, что в текущем каталоге, уже существует.
Внезапно выяснилось, что кроме «меньше пятидесяти» и «больше пятидесяти»:
если оно меньше 50, файл не трогаем, если больше, копируем его в папку "alert". »
существует ещё и «равно пятидесяти». Что делать в этом случае? Я, к сожалению, упустил этот момент изначально.
Вот Вам примерная болванка:
$sSourceFolder = 'C:\Мои проекты\0162'
if(Test-Path -Path $sSourceFolder -PathType Container) {
Get-ChildItem -Path "$sSourceFolder\*.xml" | ForEach-Object -Process {
if(([xml](Get-Content -Path $_.FullName -Encoding Ascii)).report.info.tTemp -gt 50) {
$oFolder = New-Item -Path ".\Alert" -ItemType Directory -ErrorAction SilentlyContinue
Copy-Item -Path $_.FullName, ($_.FullName -replace ".xml$", ".jpg"), ($_.FullName -replace ".xml$", ".txt") -Destination ".\Alert"
}
}
} else {
Write-Host "Can't find source folder [$sSourceFolder]." -ForegroundColor Red
}
rengaboy
29-05-2018, 11:13
существует ещё и «равно пятидесяти». Что делать в этом случае? Я, к сожалению, упустил этот момент изначально. »
а разве -gt не однозначно "больше"? Если нужно копировать 50, тогда указываем в параметре 49?
Тут вылезла другая проблема. Я про нее совершенно забыл. Файлы лежат в подпапках структуры типа год\месяц\число. И надо делать рекурсивный поиск.
rengaboy
29-05-2018, 11:42
а разве -gt не однозначно "больше"? Если нужно копировать 50, тогда указываем в параметре 49? »
А если нужно больше и равно, указываем -ge. Вроде так?
Тут вылезла другая проблема. Я про нее совершенно забыл. Файлы лежат в подпапках структуры типа год\месяц\число. И надо делать рекурсивный поиск. »
Попробовал изменить на Get-ChildItem -Path "$sSourceFolder" -Include *.xml -Recurse, но что-то не выходит каменный цветок.
rengaboy
29-05-2018, 12:38
Разобрался, заработало. В объявлении переменной пути надо было слеш добавить в конце. Проглядел.
Все копирует, но вылезает ошибка Copy-Item : Не удается скопировать элемент E:\nucmonarchive\Alert\d530f6c2d0a9b319809e8c022b69bccf.xml в самого себя. И далее на остальные два файла.
rengaboy, дело не в слэше, а в относительных путях. Ошибка вылезает, видимо потому, что Alert рядом с рабочими логами лежит.
однострок:
Get-ChildItem -Path E:\nucmonarchive -Filter *.xml -Recurse | Where-Object { [int](Select-Xml -Path $_.FullName -XPath "/report/info/tTemp").Node.'#text' -lt 50 } | Select-Object -ExpandProperty FullName | ForEach-Object { foreach($ext in @('.jpg', '.txt', '.xml')) { $_.Remove($_.Length-4)+$ext } } | Copy-Item -Destination E:\Alert
Если нужно копировать 50, тогда указываем в параметре 49? »
Причём тут параметр? Мы не можем управлять его содержимым по определению. Мы используем оператор «больше или равно»:
… -ge 50)
Тут вылезла другая проблема. Я про нее совершенно забыл. Файлы лежат в подпапках структуры типа год\месяц\число. И надо делать рекурсивный поиск. »
Сделали рекурсивный поиск. Копируем найденное и подходящее по условию в каталог Alert, находящийся/создаваемый в текущем каталоге. Очередные найденные и отобранные по условию имена файлов совпали с уже находящимися в Alert. И что делать? Видите, как легко попасть впросак с непродуманным в голове в деталях подходом на авось.
Попробовал изменить на Get-ChildItem -Path "$sSourceFolder" -Include *.xml -Recurse, но что-то не выходит каменный цветок. »
Просто добавить параметр «-Recurse» к командлету:
Get-ChildItem -Path "$sSourceFolder\*.xml" -Recurse
Все копирует, но вылезает ошибка Copy-Item : Не удается скопировать элемент E:\nucmonarchive\Alert\d530f6c2d0a9b319809e8c022b69bccf.xml в самого себя. И далее на остальные два файла. »
Вот и ещё один пример непродуманного подхода, когда внезапно™ текущий каталог для скрипта совпадает с исходным каталогом. Естественно, файл нельзя скопировать сам в себя.
Продумайте ещё раз алгоритм работы. И прежде всего — где, что и куда.
$src = 'd:\TEMP\test' # корневой каталог для сканирования
$dst = 'd:\TEMP\alarm' # целевой каталог
$node = 'tTemp' # узел, используемый для фильтрации
dir $src -inc *.xml -rec -file|%{
$a = @(
$_.fullname
$_.directoryname+'\'+$_.basename+'.jpg'
$_.directoryname+'\'+$_.basename+'.txt'
)
if([int](([xml](gc $_.fullname -enc default)).selectnodes("//$node").'#text') -ge 50){
cp $a $dst -whatif
}
}
- нет проверки на наличие целевых файлов идентичным исходным (этого нет в условии, видимо уникальные наименования)
-whatif - удалить в боевом режиме
rengaboy
29-05-2018, 15:35
Благодарю за помощь, разнес каталоги. Все работает.
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.