#powershell
#powershell
Вопрос:
У меня есть файл с именем collection.xml который содержит список фильмов из моей коллекции пасхальных фильмов, показанный ниже. Как только я получу их, я пытаюсь использовать Split для разделения файлов на строки «Movies /» и . Это приведет к появлению таких названий фильмов, как:
Пасхальный кролик приезжает в город (2006).mp4
Я пробовал различные перестановки Split() и модификатора -split . Как я могу разделить вывод ниже, чтобы получить только названия фильмов, как показано выше?
Get-Content .collection.xml | Select-String Path
<Path>/volume1/Media Library/Movies/Here Comes Peter Cottontail (1971).mp4</Path>
<Path>/volume1/Media Library/Movies/Here Comes Peter Cottontail - The Movie (2005).mp4</Path>
<Path>/volume1/Media Library/Movies/The Easter Bunny is Coming to Town (2006).mp4</Path>
<Path>/volume1/Media Library/Movies/Its The Easter Beagle Charlie Brown (2008).mp4</Path>
<Path>/volume1/Media Library/Movies/Hop (2011).mp4</Path>
<Path>/volume1/Media Library/Movies/Peter Rabbit (2018).mp4</Path>
Ответ №1:
Это просто, если вы рассматриваете это как XML-файл, полный имен файлов, поскольку вы можете сделать это в одной строке; Я разбил на несколько для удобства чтения:
Вариант 1:
([xml](get-content temp.txt)).SelectNodes("//Path") | foreach-object {
[io.path]::GetFileNameWithoutExtension($_.'#text')
}
Это эффективно:
- Считывает файл в формате XML
- Выбирает все узлы «пути» в файле — возможно, вам потребуется настроить это, чтобы лучше соответствовать вашему фактическому XML-файлу. Это простой XPath.
- Для каждого найденного узла вызовите .Собственный метод NET над текстовой частью узла для извлечения имени файла
Вариант 2:
Практически то же самое, но с использованием более собственных командлетов XML, что может упростить чтение:
(select-xml -xpath '//Path' -path .temp.txt).Node | foreach-object {
[io.path]::GetFilenameWithoutExtension($_.'#text')
}
Опять же, настройте XPath в соответствии с вашим XML-файлом.
Существуют различные способы структурирования обоих из них на ваш вкус (и точного формата XML), перемещая селекторы «.Node» и «.’#text'» внутри (или снаружи) foreach; например, мы можем убрать скобки select-xml
в строке выше, переместив узел в пределахforeach:
select-xml -xpath '//Path' -path .temp.txt | foreach-object {
[io.path]::GetFilenameWithoutExtension($_.Node.'#text')
}
…и вариации на тему. На это может повлиять ваша структура файла XML; все остальное зависит от личных предпочтений и удобства чтения.
Комментарии:
1. Спасибо, это работает идеально! Для этого я должен был использовать XML-инструменты PowerShell. Скажите мне, что такое параметр ‘#text’?
2. XML-файл — это просто набор узлов. Текст между открывающим и закрывающим тегами в XML — это сам узел, который (в случае Powershell) он присваивает
#text
псевдо-узлу. Итак, если вы просто сделаете (скажем)(select-xml -xpath '//Path' -path file).Node
, вы увидите, что вывод — это содержимое всех ваших узлов пути в столбце с заголовком (т. Е. Свойством)#text
. Если вы это сделаете(select-xml -xpath '//Path' -path file).Node | get-member
, это покажет, что#text
свойство имеет типXmlElement
. Доступ#text
как свойство в PS затем просто дает текстовое значение (через неявноеToString()
).3. Я должен добавить,
#text
в одинарных кавычках в основном ответе, потому что свойства Powershell не могут (обычно) начинаться со специальных символов. Поэтому для экранирования имени пропети нужны одинарные кавычки (и не выдавать синтаксическую ошибку).
Ответ №2:
Поскольку я не знаю, как выглядит ваш полный XML-файл, я сделал это, используя только предоставленную вами информацию и несколько простых регулярных выражений.
Здесь я делаю пару предположений
- Ваш путь к файлу всегда заканчивается на «Фильмы»
- Вам не нужен тип файла в конце строки
$banana = Get-Content C:Tempcollection.xml | Select-String Path
foreach($line in $banana)
{
#load the line as an xml object, expand the path property, and replace the characters we don't want.
([xml]$line).Path -replace "^/. Movies/|.. $"
}
Эти иероглифы после -replace
означают это
^
: Начало строки
/
: Буквенный /
символ
.
: Любой символ (кроме символов завершения строки)
: Хотя бы один, но до бесконечности
Movies
: Литеральная строка «Фильмы»
/
: Буквенный /
символ
|
: Или
.
: Буквенный .
символ (точка)
.
: .
и
комбинированный, что означает любой символ хотя бы один раз, но до бесконечности
$
: Конец строки