Как экранировать квадратные скобки в путях к файлам с помощью параметра -OutFile в Invoke-WebRequest - PullRequest
1 голос
/ 26 апреля 2019

Когда вы включаете что-то вроде [1] в имя файла, например File[1].txt, используемое с параметрами Invoke-WebRequest и -OutFile, вы получаете ошибку Cannot perform operation because the wildcard path File[1].txt did not resolve to a file.

Это вызвано задокументированным поведением здесь .

С другими командлетами вы бы использовали -LiteralPath, чтобы заставить путь быть взятым буквально, но в этом случае это не вариант.

Я пытался экранировать символы [ и ] с помощью `или \, но все равно выдает ту же ошибку.

Чтобы упростить тестирование, вы можете воспроизвести ту же проблему с Out-File, Test-Path и т. Д.

#Fails
Out-File -FilePath "file[1].txt"
Out-File -FilePath "file`[1`].txt"
Out-File -FilePath "file\[1\].txt"

#Succeeds
Out-File -LiteralPath "file[1].txt"

#Fails
Test-Path -Path "file[1].txt"

#Succeeds
Test-Path -LiteralPath "file[1].txt"

Как я могу экранировать символы, которые будут использоваться для выражения подстановочных знаков в -Path, -FilePath, -OutFile и т. Д., Чтобы они функционировали так, как строка была указана с помощью -LiteralPath, поскольку -LiteralPath не доступно с Invoke-WebRequest?

1 Ответ

1 голос
/ 26 апреля 2019
  • К сожалению, Invoke-WebRequest и Invoke-RestMethod пока не поддерживают
    -LiteralPath, как вы заявляете, но связанная с проблема GitHub показывает, что поддержка будет добавленав будущем.

  • Экранирование символов [ и ] как `[ и `], так что они обрабатываются буквально при интерпретации как подстановочное выражение с -Path (-FilePath), к сожалению, на данный момент работает только half , из-за ошибки , обсуждаемой внижняя часть:

    • Выполнение экранирования гарантирует, что параметр -Path принимает путь (команда больше не прерывается) ...

    • ... но при создании файла это ошибочно экранированное представление, которое используется как литерал имени файла - см.нижняя часть.

Обходной путь на данный момент:

  • Используйте экранирование, детализированное ниже ...
  • ... и затем переименуйте файл для удаления нежелательных ` символов.
# Literal input path.
$literalOutFile = 'file[1].txt'

# Create escaped wildcard-pattern representation that -OutFile accepts.
$escapedOutFile = [WildcardPattern]::Escape($literalOutFile)

# Call Invoke-RestMethod -OutFile with the escaped representation.
'hi' |  Out-File -FilePath $escapedOutFile

# # Rename the resulting file to compensate for the bug discussed below.
# # !! Note how the *escaped* path must be passed to -LiteralPath, because
# # !! the bug causes the output file to be created with the *escaped* name.
Rename-Item -LiteralPath $escapedOutFile ($escapedOutFile -replace '`')

Когда ошибка будет исправлена, этот код должен продолжать работать- при условии, что ваши имена файлов никогда не содержат встроенных букв ` - символов.- хотя в этом случае вызов Rename-Item будет невозможен.


Экранирующие пути [literal] для использования в качестве шаблонов подстановочных знаков:

Используйте любую из следующих строк-literal представления, которые в конечном итоге приводят к одной и той же строке с дословным содержимым file`[1`].txt, которая при интерпретации как подстановочное выражение представляет собой экранированный эквивалент буквенной строки file[1].txt:

  • 'file`[1`].txt'
  • "file``[1``].txt"
  • file``[1``].txt

Чтобы создать это экранирование программно, используйте:

$literalName = 'file[1].txt'
$escapedName = [WildcardPattern]::Escape($literalName) # -> 'file`[1`].txt'

Важно, чтобы целевой командлет воспринимал [ и ] как ` - в аргументе -Path (-FilePath) этопередается для их дословной обработки.

Если вы используете "..." в кавычках или без кавычек (который в основном ведет себя так, как если бы он был заключен в "..."), PowerShell Строка синтаксический анализ мешает: ` также используется в качестве escape-символа внутри расширяемых строк ("..."), поэтому в илиЧтобы пропустить ` через , вы должны избежать его, так как ``.

  • В противном случае что-то вроде `[ внутри "..." превращается в [- ` «съеден» - потому что `[ является экранированным [ с точки зрения "...", и экранирование персонажа, который не нуждается в экранировании, превращается просто в этого персонажа;вкратце: и "file`[1`].txt", и file`[1`].txt превращаются в простые file[1].txt, как если бы вы никогда не использовали `.

В отличие от них ` символы используются дословно внутри '...' строки в кавычках и не нуждаются в экранировании.


Дефектное поведение при создании файлов многих командлетов с -Path:

Ошибка , упомянутая выше, -file creation представление escape ошибочно используется как буквальное имя файла - влияет на большинство командлетов , к сожалению: то есть они неожиданно сохраняет *1155* символов в экранированном шаблоне на , создавая файл , так что, указав -Path 'file [1 ].txt', вы получитефайл с буквальным названием file`[1`].txt.

К счастью, большинство командлетов do поддерживают -LiteralPath, поэтому использование -LiteralPath file[1].txt в любом случае является лучшим выбором и позволяет избежать этой ошибки.

Некоторые из затронутых командлетов:

  • Invoke-WebRequest и Invoke-RestMethod

  • Out-Fileи, следовательно, операторы перенаправления > и >>, которые эффективно вызывают Out-File за кадром.

    • Обратите внимание, что Set-Content и Add-Content do не проявляют эту проблему.
  • Все (?) Export-* командлеты.

  • Другие?

Об этой ошибке сообщается в этой проблеме GitHub .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...