【问题标题】:PowerShell: Delete similar lines from filePowerShell:从文件中删除类似的行
【发布时间】:2017-10-17 11:18:20
【问题描述】:

考虑文件tbl.txt150 万行),构建如下:

Num1 ; Num2 ; 'Value' ; 'Attribute'

所以tbl.txt 看起来像:

63; 193; '绿' ; '颜色' 152; 162; '高的' ; '尺寸' 230; 164; '130 磅' ; '重量' 249; 175; '绿' ; '颜色' *重复'值'和'属性'* 420; 178; '8' ; '鞋号' 438; 172; '高的' ; '大小' *重复'值'和'属性'*

我怎样才能在'Value''Attribute' 上保留第一条唯一行 并删除'Value''Attribute' 上的以下重复行?

结果应该是这样的:

63; 193; '绿' ; '颜色' 152; 162; '高的' ; '尺寸' 230; 164; '130 磅' ; '重量' 420; 178; '8' ; '鞋号'

非常感谢任何帮助。

【问题讨论】:

  • 您尝试过什么,您尝试过什么失败了?理想情况下,您应该提供一个minimal reproducible example 来说明您的尝试,并包含有关它如何失败的具体信息,以及错误消息和/或错误输出。 SO 不是代码编写服务;最好的问题是那些提供有用信息的问题,以便回答的人可以指导您设计自己的正确答案。见How to Ask
  • 使用上面的搜索框并查看一些关于唯一值的现有问题,它们应该有助于为您指明正确的方向。喜欢这个:Powershell - filtering for unique values
  • 最初我希望相应地修改cat tbl.txt | Get-Unique,但没有找到解决方案。 @James 我还看不出如何将Foreach-Object { $_.Substring(0,2) } | Select-Object -unique 变成合适的解决方案,因为线路的长度会有所不同。
  • 如何修改cat tbl.txt | Group { $_.Substring(10,15) } | select Name | sort-object -Property Name -Unique Select-Object -unique以便返回Group的Value?
  • 我会用分隔符和标题参数为您指明Import-CSV 的方向。

标签: regex powershell text-manipulation


【解决方案1】:

假设您的数据没有标题:

Import-CSV "C:\folder\data.txt" –Delimiter ";" -Header Num1,Num2,Value,Attribute | Sort-Object -Property Value -Unique

给出你想要的输出:

Num1 Num2 Value     Attribute 
---- ---- -----     --------- 
230  164  '130lbs'  'Weight'
420  178  '8'       'Shoesize'
63   193  'Green'   'Color'
152  162  'Tall'    'Size'

您可以使用 Export-CSV 导出您的结果:

Import-CSV "C:\folder\data.txt" –Delimiter ";" -Header Num1,Num2,Value,Attribute | Sort-Object -Property Value -Unique | Export-CSV "C:\folder\data2.txt" –Delimiter ";" -NoTypeInformation

【讨论】:

    【解决方案2】:

    通过Get-Content 循环遍历文本文件,通过字符串操作分隔'Value' ; 'Attribute' 列,然后使用哈希图检查您是否已经处理过类似的行——如果没有,则输出该行一次。在代码中:

    $map = @{};
    Get-Content tbl.txt | ` 
                 %{ $key = $_.Substring($_.IndexOf(';',$_.IndexOf(';')+1)+1); `
                    If(-not $map.ContainsKey($key)) { $_; $map[$key] = 1 } `
                  } 
    

    或者,如 cmets 中所述,您可以使用 group 并应用与分组标准相同的子字符串,最后取每个组的第一个元素:

    Get-Content tbl.txt | group {$_.Substring($_.IndexOf(';',$_.IndexOf(';')+1)+1)} `
                        | %{$_.Group[0]}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-30
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-10
      相关资源
      最近更新 更多