How to read text in .txt file and each of its value in powershell?

笑着哭i 提交于 2019-12-11 09:02:23

问题


I have data in a text file like below, i want to read it value by value using 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

For example i want to read value for name in 2nd field. How can it be read?


回答1:


It is difficult to convert it without having a delimiter in place. With a delimiter you could make use of ConvertFrom-String

If we would use ConvertFrom-String with this format, it will parse the first 2 columns correctly, but the description will be seperated in words.

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

Result:

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

To get the second result you have to take in account the header and separator line. This will return the full object.

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

Result:

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

This will only return the value from "Enabled"

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

Result:

True



回答2:


Best transform the text into an object with properties again.

This is quite easy as the 1st two columns don't have spaces in the values,
so this one liner:

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

yields this output:

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

Looks familiar?

Yes, but stored in a variable i.e. $Data = ...,
allows you to directly acsess the 2nd Name (index is zero based) with

> $Data[1].Name
Azureuser

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

To better explain what the script does, here a dealiased version:

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

Where-Object {$_ -notmatch '^[ -]+$'} removes the line with only dashes and spaces

$_.trim(' ') removes the trrailing spaces from the lines

-split ' +',3 splits the line at any number of spaces >1 into exactly 3 pieces

which are stuck together with -join ',' forming a valid csv file with a header

The final | ConvertFrom-Csv does the work.




回答3:


Parsing that kind of format is not easy, but here is an attempt:

$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

This will work properly for all 3 columns. Even with spaces in the values. (The script will break, if there are spaces in the header names, but this is usually not the case.)




回答4:


For example i want to read value for name in 2nd field. How can it be read?

If I do not misunderstand, you want to read Azureuser in the txt file, try the command below, $txt[3].Split()[0] is what you want.

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



来源:https://stackoverflow.com/questions/55489841/how-to-read-text-in-txt-file-and-each-of-its-value-in-powershell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!