从文件块行中删除

时间:2014-10-27 10:33:56

标签: regex powershell

我有一个文本文件,其中信息ID以行块的形式组织。 我需要删除包含一些信息的块。

例如我有以下

dn: CN=Publishers,OU=ABC - Groups 
changetype: add 
cn: Cert 
description:   Members of this group are permitted to ... 
groupType: -2 
objectClass: top 
objectClass: group

dn: CN=Domain Guests,OU=ABC - Groups, 
changetype: add 
cn: Domain Guests 
description: All domain guests 
groupType: -21 
objectClass: top
objectClass: group

dn: CN=Domain Computers,OU=ABC- Groups 
changetype: add 
cn: Domain Computers 
description: All workstations  
groupType: -2 
objectClass:top 
objectClass: group

dn: CN=AS Servers,OU=ABC- Groups 
changetype: add 
cn: AS   Servers
description: Servers in this group... 
groupType: -214
objectClass: top 
objectClass: group

dn: CN=Domain Controllers,OU=ABC - Groups 
changetype: add 
cn: Domain Controllers 
description: All domain controllers in the domain
groupType: -21 
objectClass: top 
objectClass: group

dn: CN=Domain Users,OU=ABC - Groups 
changetype: add 
cn: Domain Users
description: All domain users 
groupType: -21 
objectClass: top
objectClass: group

我需要移除例如名称包含在另一个文件中的块,例如某些块的第一行在其他文件中(例如CN=Domain Computers,OU=ABC- Groups and CN=AS Users,OU=ABC- Groups (those bellow)

我的代码:

$listsharedCN=Get-content "shared.txt
$exported_groups= Get-Content "groups.txt
$listsharedCN | % {
$var=($_ -split '`n')[0]

if(($exported_groups | % { ($_ -split '`n')[0] }) -match[regex]::Escape($var)) 
 {
    #I found the first line of the block but need to delete this block  "
 }  

任何人都可以帮助我吗?

3 个答案:

答案 0 :(得分:0)

dn:\s+CN=(?:Domain\s+Computers|AS\s+Users),OU=ABC\s*-\s+Groups.*?\n

你可以试试这个。empty string。见。演示。

http://regex101.com/r/sU3fA2/10

答案 1 :(得分:0)

目前还不完全清楚你要做什么,所以我会给你一些一般性的指导。您可以将此文件转换为CSV格式的文件,然后使用ConvertFrom-Csv将其读入。然后,您可以使用一系列适当的对象。

示例(您可以将所有这些放在一行):

Get-Content .\ExportGroups.ldf | % { $_ -replace ' (\w+:)', ';' -replace 'dn: ', ''} | 
  ConvertFrom-Csv -Delimiter ';' -Header DN, ChangeType, CN, Description, GroupType, ObjectClass, ObjectClass2

我会解释它,因为它有点神秘。

  • 使用Get-Content
  • 获取文件的所有行
  • 使用-replace与正则表达式创建有效的CSV格式的行
  • 使用ConvertFrom-CSV
  • 从CSV创建PowerShell对象

答案 2 :(得分:0)

虽然我不确定你对这些数据到底做了什么,如果它是一个物体,它将更容易操纵它......我们应该这样做! 来自评论:在我发现事后您正在对数据做了什么之后,我觉得我过于复杂了。虽然这应该工作,但我建议如果你有一个问题,把一些代码与输入数据(如果需要)和期望。

$rawFile = Get-Content -Raw -Path E:\temp\data.txt
$excludesFile = Get-Content -Path E:\temp\shared.txt

$ldifdes = $rawFile -split '\s+(?=dn:)' | ForEach-Object{
    # Empty hashtable that we will use to build a single custom object
    $props = @{}

    $entityObject = $_ -split "`r`n" 

    # Parse out the object class. Custom object cannot have more than one key
    # so we convert to Array instead.
    $entityObject | Where-Object{$_ -notmatch 'objectclass'} | ForEach-Object{
        # Populate the object that are not objectclass into $props
        $parameter = $_ -split ":"
        $props.($parameter[0]) = ($parameter[1]).Trim()
    }

    # Address the objectclass now.
    $props.ObjectClass = @()
    $entityObject | Where-Object{$_ -match 'objectclass'} | ForEach-Object{
        $props.ObjectClass += (($_ -split ":")[1]).Trim()
    } 

    New-Object -TypeName pscustomobject -Property $props
}

# Filter out the entries we do not need.
$regex = "($($excludesFile -join "|"))"
$ldifdes | Where-Object{$_.DN -notmatch $regex} | ForEach-Object{
    Write-Output "dn: $($_.DN)"
    Write-Output "changetype: $($_.changetype)"
    Write-Output "cn: $($_.cn)"
    Write-Output "description: $($_.description)"
    Write-Output "groupType: $($_.groupType)"
    $_.ObjectClass | ForEach-Object{
        Write-Output "ObjectClass: $_"
    }
    # Add a blank
    Write-Output ""
} | Out-File -Encoding ascii -FilePath "E:\temp\output.txt"

如果您至少拥有powershell 3.0,则此代码将起作用。如果需要,降级不是什么大不了的事。没有详细说明:

  1. 阅读文件原始内容
  2. 将这些内容拆分为变量组
  3. 对于那些组中的每一个再次拆分成一个字符串数组
  4. 对于按冒号分割的字符串数组中的每个字符串,以获取键和值
  5. 异常是ObjectClass,我们将其转换为数组,因为哈希表需要具有唯一键
  6. 构建我们要排除的项目的正则表达式,并使用Where-Object
  7. 解析它们
  8. 为了简单起见(因为我觉得我做得更糟)使用一系列Write-Ouput来显示ldifde的数据
  9. 管道进入Out-File
  10. 不太复杂

    $rawFile = Get-Content -Raw -Path E:\temp\data.txt
    $excludesFile = Get-Content -Path E:\temp\shared.txt
    $regex = "($($excludesFile -join "|"))"
    
    $results = $rawFile | select-string -pattern '(?smi)(dn:).*?(?=dn:|\Z)' -AllMatches | Foreach {$_.Matches} | ForEach-Object {$_.Value.Trim()}
    
    $results | Where-Object{ $_ -notmatch $regex } | ForEach-Object{$_ + [Environment]::NewLine} | 
            Out-File -Encoding ascii -FilePath "E:\temp\output.txt"
    

    将字符串解析为块组。像以前一样构建$regex字符串,并将其用作Where-Object中的排除项。然后使用Out-File

    输出到文件