2016-11-18 6 views
2

У меня есть несколько видеофайлов, подобных этому: VideoName_s01e01.mp4 где сезон и эпизоды являются переменными. Я хочу добавить символ подчеркивания («_») между s?? и e??.Переименование файлов путем переформатирования существующих имен файлов - заполнителей в строках замещения, используемых с оператором -обмена

Я использую для переименования целей, у меня есть отправная точка:

GCI $path -filter '*_s??e??*' -rec | Ren -new { $_.name -replace '_s[0-9][0-9]', '_s[0-9]_[0-9]_' } -passthru  

Это фактически переименованный мои файлы VideoName_s[0-9]_e[0-9].mp4.

В принципе, я ищу символы s??e?? Я просто не знаю, как сделать их переменными в разделе замены.

Я думаю, что лучший метод был бы:

  1. Найти позицию e??s?? (назовем его X).
  2. разделил строку на X-3.
  3. объединить строку с «_» в середине.

ответ

4

Martin Brandl's answer provides an elegant and effective solution, но это стоит копать глубже:

PowerShell в -replace оператор (... -replace <search>, <replace>):

  • принимает регулярное выражение в качестве первого операнда, <search>, выражения поиска), и неизменно соответствует глобально (находит все матчей).

  • поддерживает ссылки на то, что регулярное выражение захватило (и не зафиксировало) во втором операнде, <replace>, заменяющую строку (строку подстановки).

«Язык замены» для ссылки на регулярное выражение захватывает поддерживаемые в <replace> сама не регулярного выражения - нет соответствий не происходят там, только ссылки на результатов согласующих регулярных выражений поддерживаются.

Следует отметить, что

Для удобства, здесь ссылки поддерживаются в <replace> (Выдержки из страницы связаны выше, с акцентом и аннотации добавлены):

  • $number (например, $1) ... Включает последнюю подстроку, соответствующую группе захвата , которая идентифицируется number, где number является десятичным значением в заменяющей строке.

    • Аннотация:

      • В том числе, в круглых скобках (...) в своем регулярном выражении неявно создает неназванного захвата (захват) группу. Без имени группы ссылаются индекса, начиная с 1, так что $1 относится к тому, что первая группа неназванных в своем регулярном выражении захватил, $2 к тому, что захватили второй, ...
        Таким образом, что первый ([0-9]{1,2}) в ответ Мартина, после s, зафиксированный, отражается в $1, а вторая неназванная группа, после e, в $2.

      • Форма ${number} (например, ${1}) для неоднозначности числа также поддерживается (например, чтобы убедиться, что $1 признается, даже если им следовать, скажем, 000, использовать ${1}000).

  • ${name} ... Включает в себя последнюю подстроку, совпавшего с названием группы обозначенная (?<name>...) в строке замены.

  • $$ ... Включает один "$" буквального в строке замены.

  • $& ... Включает в себя копию всего матча в заменяемой строке.

  • $` ... Включает в себя весь текст на входной строки перед тем матч в строке замены.

  • $' ... Включает в себя весь текст на входной строки после матча в строке замены.

  • $+ ... Включает в себя группу последний захватили в строке замены. [Это избавляет вас от необходимости знать конкретный индекс последней группы.]

  • $_ ... Включает всего входного строку в строке замещения.

Наконец, следует отметить, что:

  • Это как правило, предпочтительно использовать '...' как для регулярного выражения и строки подстановки. I.e., используйте одиночные кавычки, которые нерасширяются (не интерполируются) и, следовательно, избегают путаницы с собственными досрочными расширениями PowerShell для токенов $.
    Если вам необходимо включить переменную PowerShell, у вас есть два варианта:

    • Используйте "..." (расширяющиеся строки) и ` экранирующего $ экземпляров, которые предназначены для регулярных выражений; например, `$1 в следующем примере:
      'abc' -replace '(a)', "[`$1]-$HOME-", что дает что-то вроде [a]-C:\Users\jdoe-bc
    • Создайте свою строку из буквенных частей и ссылок на переменные с помощью конкатенации (+); например .:
      'abc' -replace '(a)', ('[$1]-' + $HOME + '-')
  • -replace неизменно соответствует глобально, поэтому, если входная строка содержит несколько матчей, замены выше, применяются к каждый матч.

+1

Я хотел бы upvote дважды ... –

1

-replace использует , не . Таким образом, вы должны заменить замену на:

-replace '_s([0-9]{1,2})e([0-9]{1,2})', '_s$1_e$2_' 
1

Я настоятельно рекомендую regex101.com для изучения регулярного выражения.

Что-то, как это может работать:

"VideoName_s01e01.mp4" -replace '(.*s)(\d+)(e.*)', '$1$2_$3' 

Дает:

VideoName_s01_e01.mp4 
0

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

$exampleoffile = @" 
namev1_s01e01.mp4 
namvev2_s03e02.mp4 
VideoName_s20e15.mp4 
VideoName_s15e1.mp4 
VideoName_s1e16.avi 
VideoName_s1e23.mv 
"@ 

[email protected]" 
{file*:{prefix:Test1}_s{season:01}e{episode:01}{extension:.mp4}} 
{file*:{prefix:1xxx}_s{season:100}e{episode:5}{extension:.mp4}} 
{file*:{prefix:yyy3}_s{season:10}e{episode:02}{extension:.havi}} 
"@ 



$exampleoffile | ConvertFrom-String -TemplateContent $template | 
% { "{0}_{1:D2}_e{2:D2}{3}" -f $_.file.prefix, [int]$_.file.season, [int]$_.file.episode, $_.file.extension }