【问题标题】:How to save select-string output from bulk text files to an array powershell如何将批量文本文件中的选择字符串输出保存到数组 powershell
【发布时间】:2018-05-19 18:00:29
【问题描述】:

我正在尝试从文本文件中批量提取子字符串,并将这些子字符串保存到数组中。我尝试了以下变体。这会将所有选定的字符串输出到屏幕,但仅将最终输出保存到变量。有没有办法模仿 =+ 运算符的功能,以便所有项目都存储在数组中?

$FILES = ls "*.txt"
foreach($f in $FILES){
  $in=Get-Content $f
  $in | Foreach { Select-String -Path "$f" -Pattern "Ad ID" -outvariable 
  array1 }}

如果我的策略被误导,将子字符串拉入数组的总体目的是让这些文本文件的多个单独子字符串数组。然后我会将这些值连接到一个 csv 中。我试图拉出元素而不是重新排列文本文件,因为文本文件中的子字符串的顺序不同。示例:

文本文件一:

Ad Id: xxxx
Ad Text: blah blah
Ad placement: spaceship

文本文件二:

Ad Id: yyyy
Ad placement: zoo
Ad Text: blah blah

最终想要的结果(这部分工作除了元素的顺序)

CSV 文件

xxxx, spaceship, blah blah
yyyy, zoo, blah blah

【问题讨论】:

    标签: arrays powershell select-string


    【解决方案1】:

    这是一种构建您正在谈论的数组的方法。我不认为这是解决这个问题的最好方法。这对结果的顺序没有任何影响,也不会创建 .csv 文件。

    $FILES = Get-ChildItem -File -Filter "*.txt"
    
    $array1 = $()
    
    foreach($f in $FILES) {
        Get-Content -Path $f |
            Select-String -Pattern "Ad Id.*" |
            ForEach-Object { $array1 += @($_.Matches.Value) }
    }
    
    $FILES.Count
    
    $array1.Count
    $array1
    

    【讨论】:

    • 太棒了——这正是我想要做的。完全正确的结果顺序也需要解决。但这在这一步中按预期工作。谢谢!
    • 另外,关于结果的顺序。这保持了目录中 txt 文件的顺序。用“Ad Id.*”替换其他元素也保持相同的顺序。所以我假设这将适用于其他字段并允许在 csv 中重新配对子字符串。
    【解决方案2】:

    试试这个:

    $files      = ls "*.txt"
    $dictionary = @{}
    
    foreach($f in $files) {
        $in = Get-Content $f
        $in.Split([Environment]::NewLine) | ForEach-Object {
            $key,$value = $_.Split(':')
            $dictionary[$key] = $value
        }
        $dictionary['Ad Id'] + ', ' + $dictionary['Ad placement'] + ', ' + $dictionary['Ad Text'] | Out-File -FilePath '.\results.csv' -Append
    }
    

    排序输出:

    $files      = ls "fil*.txt"
    $dictionary = @{}
    [System.Collections.Generic.List[String]]$list = @()
    
    foreach($f in $files) {
        $in = Get-Content $f
        $in.Split([Environment]::NewLine) | ForEach-Object {
            $key,$value = $_.Split(':')
            $dictionary[$key] = $value
        }
        [void]$list.Add( $dictionary['Ad Id'] + ', ' + $dictionary['Ad placement'] + ', ' + $dictionary['Ad Text'] )
    }
    [void]$list.Sort()
    $list | Out-File -FilePath '.\results.csv' -Append
    

    【讨论】:

    • 这是一个非常有用的回复。我明白为什么我想以这种方式解析 txt。通过上述 results.csv 推送 txt 文件后,返回为空 csv(只是逗号)。为了简单起见,我在上面没有提到其他由冒号分隔的字段。您知道我是否需要将它们全部添加为 $dictionary 中的键才能使这种方法起作用?并感谢您的彻底回答!
    • 换句话说,如果触发拆分的冒号多于字典列表中的可用键,那么这可能是导致输出混乱的原因吗?
    • 我不确定我是否正确。你能举例说明你的意思吗? (输入/预期输出)。
    • 所以$files里面的txt文件其实有很多字段,后面跟冒号。比添加到字典中的要多(或者比我的原始示例中的要多)。示例:年龄:,语言:,广告创建日期:等。我想看看它是否可以将所有带冒号的字段添加到行 [void]$list.Add.. 我认为存在的冒号比广告多Id、广告展示位置和广告文字可能会影响输出?
    • 没关系——让它工作。我上面使用的示例字段与实际字段名称略有不同。谢谢!
    【解决方案3】:

    另一种略有不同的方法。

    • RegEx 解析 $Line 并创建一个名称在冒号之前的变量(不带 Ad)并赋值后面的内容
    • 在每个处理过的文件之后,vars 都会作为自定义对象输出

    $Data = ForEach ($File in (Get-ChildItem File*.txt)){
        $Id,$Text,$Placement="","",""
        ForEach ($Line in (Get-Content $File)){
            If ($Line -Match "AD (?<Label>.*?): (?<Value>.*)"){
                Set-Variable -Name "$($Matches.Label)" -Value $Matches.Value
            }
        }
        [PSCustomObject]@{ID        = $Id
                          Placement = $placement
                          Text      = $Text}
    }
    $Data
    $Data | Export-CSv ".\Result.csv" -NoTypeInformation
    

    样本输出:

    ID   Placement Text
    --   --------- ----
    xxxx spaceship blah blah
    yyyy zoo       blah blah
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 2017-11-05
      • 2021-08-24
      • 1970-01-01
      • 1970-01-01
      • 2017-10-07
      • 1970-01-01
      相关资源
      最近更新 更多