get-content не возвращает полную строку, если только одна строка в .txt - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть скрипт для установки дополнительных файлов в установленную программу, где может существовать много версий этой программы. Установщик работает великолепно, если есть несколько установок (у моего p c было 22), но приглашение не может правильно написать приглашение выбора местоположения, если оно только одно.

$count = 1
foreach($line in (gc $scriptPath\ExoInst.txt)) 
{
    if($line -match $regex)
    {
        Write-Host $count":"(gc $scriptPath\ExoInst.txt)[$count-1]
        $count++
    }
}

Это код ошибки, он просто пишет 1: C для запроса, даже если в ExoInst.txt есть полное место установки.

Простое gc в .txt получает полный текст.

Скриншот добавлен. Ошибка кода

Не уверен, что это странное поведение с ":" или что.

Спасибо за помощь!

1 Ответ

2 голосов
/ 28 апреля 2020

Проблема в том, что для текстовых файлов, которые содержат только одну строку текста, Get-Content возвращает String, а не массив String[]. Вы можете увидеть это на следующем примере:

PS C:\> $SingleLine = Get-Content .\SingleLineOfText.txt
PS C:\> $SingleLine
OnlyOneLine
PS C:\> $SingleLine[0]
O
PS C:\> $SingleLine.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

PS C:\> $MultiLine = Get-Content .\MultipleLinesOfText.txt
PS C:\> $MultiLine
OneLine
TwoLine
ThreeLine
PS C:\> $MultiLine[0]
OneLine
PS C:\> $MultiLine.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

Так что происходит только с одной строкой текста, возвращая объект String, оператор (gc..)[0] возвращает только первый символ в строке, а не «ожидаемая» первая строка.

Решение состоит в том, чтобы убедиться, что Get-Content возвращает массив. Мы можем сделать это, поместив его в оператор Array Sub Expression т.е. @( ... ) примерно так:

PS C:\> $SingleLine = @(Get-Content .\SingleLineOfText.txt)
PS C:\> $SingleLine
OnlyOneLine
PS C:\> $SingleLine[0]
OnlyOneLine
PS C:\> $SingleLine.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

Таким образом, ваш код становится (с незначительным форматированием для вывода):

$count = 1
foreach($line in @(gc $scriptPath\ExoInst.txt)) 
{
    if($line -match $regex)
    {
        Write-Host $count":$(@(gc $scriptPath\ExoInst.txt)[$count-1])"
        $count++
    }
}

РЕДАКТИРОВАТЬ:

Или, что я хотел бы сделать, это сначала прочитать файл, а затем использовать вашу $line переменную ... , потому что она содержит строку, которую вы работаем на ;-), для более чистого кода:

$count = 1
$ExoInst = @(gc $scriptPath\ExoInst.txt)
foreach($line in $ExoInst) 
{
    if($line -match $regex)
    {
        Write-Host $count":"$line
        $count++
    }
}
...