使用 PowerShell 读取具有未知索引的文件中的特定行



我有一个IN文件,如下所示。

;**********  Information  **********
;Date=190303
;Class_1=US13091990#1Joyce#2Female
;Phone_Number=98233215.00
;School=St.JosephJuniorHighSchool
;ID=F1
;***********************************

我想阅读特定的行,对于我想阅读的示例Class_1.但Class_1的指数要记住,指数是动态的,可能会发生变化。

$File = Get-Content .file_input
$File = Select-String "Class_1"
$File

无需担心它在文件中的显示位置。在这里利用ConvertFrom-StringData的力量。它将键值对列表转换为哈希表。

  1. 读入文件。
  2. 过滤分号,双反斜杠(因为它稍后被视为转义序列(并忽略记录边界。
  3. 存储为单个字符串并传递给ConvertFrom-StringData
  4. 转换为 PowerShell 对象

$filteredContent = (Get-Content "c:tempfile_input") -replace '^;' -replace '\','\' | Where-Object{-not $_.startswith('*')} 
$information = [pscustomobject]($filteredContent -join "`r`n" | ConvertFrom-StringData)
$information.class_1

因此,使用上述内容,这就是$information的样子。

Class_1      : US13091990#1Joyce#2Female
School       : St.JosephJuniorHighSchool
Date         : 190303
Phone_Number : 98233215.00
ID           : F1

这也将使处理更多这些记录变得更加容易,并在您需要进行更多后处理时为您提供更大的灵活性。

您可以执行以下操作来读取 INI 文件并选择包含Class_编号的行:

$a = Get-Content ini.ini
$data = $a | Select-String -Pattern "Class_d+"

从那里,您可以使用$data访问线路的不同部分。有关一些示例,请参见下文:

$NumberAfterUnderscore = ($data.matches.value -split "_")[1]
$DataAfterEqualSign = ($data -split "=")[1]
$DataBetweenEqualandPound = (($data -split "=")[1] -split "#")[0]
$DataBetweenFirstandSecondPounds = (($data -split "=")[1] -split "#")[1]
$DataAfterLastPound = (($data -split "=")[1] -split "#")[2]

以下是上述代码的输出:

$NumberAfterUnderscore
1
$DataAfterEqualSign
US13091990#1Joyce#2Female
$DataBetweenEqualandPound
US13091990
$DataBetweenFirstandSecondPounds
1Joyce
$DataAfterLastPound
2Female
$data.matches.value
Class_1
使用

Select-String 返回的对象是 MatchInfo 对象。 在尝试将结果用作字符串时,这可能会给您带来问题。 这是处理它的一种方法...并将输出解析为$vars。

您可能更愿意将该行解析为 PSCustomObject。 如果您对此有疑问并需要一些帮助,请询问。[咧嘴一笑]

代码...

# fake reading in a text file
#    in real life, use Get-Content
$InStuff = @'
;**********  Information  **********
;Date=190303
;Class_1=US13091990#1Joyce#2Female
;Phone_Number=98233215.00
;School=St.JosephJuniorHighSchool
;ID=F1
;***********************************
'@ -split [environment]::NewLine
$ThingToFind = 'Class_1'
$FoundString = $InStuff |
    Select-String -SimpleMatch $ThingToFind
# Select-String returns a MatchInfo object,
#    so it needs to be converted to a regular string before using it as such
$ID_Number, $Name, $Gender = $FoundString.ToString().Split('=')[1].Split('#')
$Name = $Name.Trim('1')
$Gender = $Gender.Trim('2')

$FoundString.ToString()
$ID_Number
$Name
$Gender

输出。。。

;Class_1=US13091990#1Joyce#2Female
US13091990
Joyce
Female

编辑

正如这里建议的那样,代码再次带有一些注释。我还编辑了部分代码,以进一步解释如何获取文件中参数的各个值。

   foreach($line in Get-Content .file_input) { #Loop though each line of the file
        if ($line.Contains("=") { #If the line contains "=" then we know that the line contains a parameter
            $splittedLine = $line.Split("=") #We know that the parameter line can be split at "=" to get parameter type and value of parameter
            $type = $splittedLine[0] #First part of line contains the type
            switch($type) { #Lets switch on the type to handle each type accordingly
                ";Date"{ #Here we have the Date type
                    $date = $splittedLine[1]
                }
                ";Class_1"{ #Here we have the Class_1 type
                    $class1 = $splittedLine[1]
                }
                ";Phone_Number"{ #Here we have the Phone_Number type
                    $phoneNum = $splittedLine[1]
                }
                ";School"{ #Here we have the School type
                    $school = $splittedLine[1]
                }
                ";ID"{ #Here we have the ID type
                    $id = $splittedLine[1]
                }
            }
        }
    }

你可以告诉你的程序,如果它在脚本中找到Class_1,则在=之后选取数据。

最新更新