简体   繁体   English

从文件行删除

[英]Delete from file block of lines

I have a text file in which the info id organized in block of lines. 我有一个文本文件,其中的信息ID以行的形式组织。 I need to delete the blocks that contain some information. 我需要删除包含一些信息的块。

For example I have the following 例如我有以下

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

And I need to remove for example the blocks which have the name contained in another file for example the first line for some blocks are in othe file (eg CN=Domain Computers,OU=ABC- Groups and CN=AS Users,OU=ABC- Groups (those bellow) 并且我需要删除例如名称包含在另一个文件中的块,例如某些块的第一行在其他文件中(例如, CN=Domain Computers,OU=ABC- Groups and CN=AS Users,OU=ABC- Groups (those bellow)

My code : 我的代码:

$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  "
 }  

Can anyone help me? 谁能帮我?

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

You can try this.Replace by empty string .See demo. 您可以尝试此操作。用empty string替换。请参见演示。

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

It's not totally clear what you are trying to do, so I will give you some general guideline. 目前尚不清楚您要做什么,所以我会给您一些一般性的指导。 You could turn this file into a CSV formatted file and then read it in with ConvertFrom-Csv. 您可以将此文件转换为CSV格式的文件,然后使用ConvertFrom-Csv读取。 You then have an array of proper objects to work with. 然后,您可以使用一系列适当的对象。

Example (you can put all of this on one line): 示例(您可以将所有这些都放在一行上):

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

I'll explain it, because it's a bit cryptic. 我会解释一下,因为它有点神秘。

  • Get all the lines of the file with Get-Content 使用Get-Content获取文件的所有行
  • Use -replace with regex to create valid CSV formatted lines 将-replace与正则表达式配合使用以创建有效的CSV格式的行
  • Create PowerShell objects from the CSV with ConvertFrom-CSV 使用ConvertFrom-CSV从CSV创建PowerShell对象

While I am not sure what exactly you are doing with this data it would be tonnes easier to manipulate it if it was an Object....... LETS DO THAT! 虽然我不确定您对这些数据的用途是什么,但是如果它是对象,则操作起来会容易得多。……请这样做! From comments: I feel like I over complicated the issue after I found out what you were doing with the data after the fact. 从评论中:在我发现事实之后,我对数据的处理方式让我感到非常麻烦。 While this should work I would suggest that if you ever have a question to put some code with input data ( if required ) and desired out. 虽然这应该可行,但我建议如果您有任何问题要在输入数据中放入一些代码(如果需要)并按要求输出。

$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"

If you have at least powershell 3.0 this code will work. 如果您至少具有powershell 3.0,则此代码将起作用。 Not a big deal to downgrade if need be. 如果需要,降级没什么大不了的。 Without going into to much detail: 无需赘述:

  1. Read the files raw contents 读取文件原始内容
  2. Split those contents into there variable groups 将这些内容分成变量组
  3. For each one of those group split again into a string array 对于这些组中的每一个,再次将其拆分为一个字符串数组
  4. For each string in the string array split by colon to get the key and value 对于用冒号分隔的字符串数组中的每个字符串,获取键和值
  5. Exception being ObjectClass which we convert into an array since a hashtable need to have unique keys 例外是ObjectClass,我们将其转换为数组,因为哈希表需要具有唯一键
  6. Build a regex of items we want to exclude and parse them out with a Where-Object 建立我们要排除的项目的正则表达式,并使用Where-Object解析它们
  7. For simplicity sake ( since i feel i made this worse ) use a series of Write-Ouput 's to display the data for ldifde 为了简单起见(因为我觉得我变得更糟),请使用一系列Write-Ouput来显示ldifde的数据
  8. Pipe into Out-File 传递到Out-File

Less Complicated 复杂程度降低

$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"

Parse the strings into block groups. 将字符串解析为块组。 Build $regex string just like before and use that as an exclusion in Where-Object . 像以前一样构建$regex字符串,并将其用作Where-Object的排除Where-Object Then just output to file using Out-File 然后只需使用Out-File输出到文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM