Как читать текст в файле .txt и каждое его значение в powershell? - PullRequest
1 голос
/ 03 апреля 2019

У меня есть данные в текстовом файле, как показано ниже, я хочу прочитать их значение по значению, используя powershell

Name           Enabled Description                                             
----           ------- -----------                                             
administrator1 True                                                            
Azureuser      True    Built-in account for administering the computer/domain  
DefaultAccount False   A user account managed by the system.                   
Guest          False   Built-in account for guest access to the computer/domain

Например, я хочу прочитать значение для имени во 2-м поле. Как это можно прочитать?

Ответы [ 4 ]

1 голос
/ 03 апреля 2019

Лучше всего снова преобразовать текст в объект со свойствами.

Это довольно просто, так как в первых двух столбцах нет пробелов в значениях,
, так что этот один вкладыш:

gc .\file.txt|?{$_ -notmatch '^[ -]+$'}|%{$_.trim(' ') -split ' +',3 -join ','}|convertfrom-csv

дает такой вывод:

Name           Enabled Description
----           ------- -----------
administrator1 True
Azureuser      True    Built-in account for administering the computer/domain
DefaultAccount False   A user account managed by the system.
Guest          False   Built-in account for guest access to the computer/domain

Выглядит знакомо?

Да, но хранится в переменной, т. Е. $ Data = ...,
позволяет напрямую получить доступ ко 2-му имени (индекс начинается с нуля) с помощью

> $Data[1].Name
Azureuser

> $Data[2].Description
A user account managed by the system.

Для улучшенияОбъясните, что делает скрипт, здесь версия с умыслом:

$Data = Get-Content .\file.txt | Where-Object {$_ -notmatch '^[ -]+$'} |
  ForEach-Object{
   $_.trim(' ') -split ' +',3 -join ','
  } | ConvertFrom-Csv

Where-Object {$_ -notmatch '^[ -]+$'} удаляет строку только с тире и пробелами

$_.trim(' ') удаляет пробелы в строках

-split ' +',3 разбивает строку при любом количестве пробелов> 1 ровно на 3 части

, которые склеиваются вместе с -join ',', образуя действительный csv-файл с заголовком

Окончательный вариант| ConvertFrom-Csv делает работу.

1 голос
/ 03 апреля 2019

Трудно конвертировать его без разделителя.С разделителем вы можете использовать ConvertFrom-String

Если мы будем использовать ConvertFrom-String с этим форматом, он будет правильно анализировать первые 2 столбца, но описание будет разделено наслова.

((Get-Content .\test.txt) | ConvertFrom-String -PropertyNames Name, Enabled)

Результат:

Name           Enabled P3          P4
----           ------- --          --
Name           Enabled Description
----           ------- -----------
administrator1 True
Azureuser      True    Built-in    account
DefaultAccount False   A           user
Guest          False   Built-in    account

Чтобы получить второй результат, вам необходимо принять во внимание заголовок и разделительную строку.Это вернет полный объект.

((Get-Content .\test.txt) | ConvertFrom-String -PropertyNames Name, Enabled)[3]

Результат:

Name    : Azureuser
Enabled : True
P3      : Built-in
P4      : account
P5      : for
P6      : administering
P7      : the
P8      : computer/domain

Это вернет значение только из «Включено»

(((Get-Content .\test.txt) | ConvertFrom-String -PropertyNames Name, Enabled)[3]).Enabled

Результат:

True
1 голос
/ 03 апреля 2019

Анализ такого формата не прост, но вот попытка:

$lineNo = 0
Get-Content .\test.txt | foreach {
    # if first line, make a regex for parsing based on the headers
    # (assumes header names have no spaces)
    if ($lineNo -eq 0) {
        $matches = [regex]::Matches($_, '\w+ +')
        $headers = $matches | foreach {$_.Value.Trim()}
        # build a regex based on column names & lengths
        $regex = $(for($i = 0; $i -lt $matches.Count; $i++) {
            if ($i -lt $matches.Count - 1) {
                $quantifier = "{" + $matches[$i].Length + "}"
            } else { $quantifier = "+" }
            "(?<$($headers[$i])>.$quantifier)"
        }) -join ""
    }
    # skip 2nd line and parse all others with the regex created before
    elseif ($lineNo -gt 1) {
        if ($_ -match $regex) {
            [pscustomobject]$matches | select $headers
        }
    }
    $lineNo++
# Now you can easily get the value you want
} | select Name

Это будет работать правильно для всех 3 столбцов. Даже с пробелами в значениях. (Скрипт прервется, если в именах заголовков будут пробелы, но обычно это не так.)

0 голосов
/ 03 апреля 2019

Например, я хочу прочитать значение для имени во втором поле.Как это можно прочитать?

Если я не понимаю неправильно, вы хотите прочитать Azureuser в текстовом файле, попробуйте команду ниже, $txt[3].Split()[0] это то, что вы хотите.

$txt = Get-Content 'C:\Users\joyw\Desktop\users.txt'
$txt[3].Split()[0]

enter image description here

...