如何读取.txt文件中的文本及其在powershell中的每个值?

时间:2019-04-03 07:53:34

标签: windows powershell azure-powershell

我在如下所示的文本文件中有数据,我想使用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

例如,我想在第二个字段中读取名称的值。怎么读?

4 个答案:

答案 0 :(得分:1)

在没有分隔符的情况下很难转换。使用定界符,您可以使用ConvertFrom-String

如果我们以这种格式使用ConvertFrom-String,它将正确解析前两列,但描述将用单词分隔。

((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 :(得分:1)

解析这种格式并不容易,但这是一种尝试:

$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列均正常工作。即使值中有空格。 (如果标题名称中有空格,则脚本将中断,但通常不是这种情况。)

答案 2 :(得分:1)

最好再次将文本转换为具有属性的对象。

这很容易,因为前两列的值中没有空格,
所以这一个衬里:

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 = ...,
允许您使用

直接访问第二个名称(索引从零开始)
> $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完成了工作。

答案 3 :(得分:0)

  

例如,我想在第二个字段中读取名称的值。怎么读?

如果我没有误会,您想阅读txt文件中的Azureuser,请尝试以下命令,$txt[3].Split()[0]是您想要的。

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

enter image description here