【问题标题】:Removing multiple strings within a text file using powershell使用powershell删除文本文件中的多个字符串
【发布时间】:2021-03-04 04:50:18
【问题描述】:

好吧,我对 PowerShell 仍然很陌生,我在这里筛选了几个不同的线程,试图找到解决这个问题的最佳方法。 This 是我能找到的最接近我需要修改文件的方式。如果他们有更好的方法来解决这个问题,我会全力以赴,就像我说的对 powershell 来说还是很新的。

目标

  • 我想删除文本文件中的整个组,然后将其写入同一个文件(如果可能)

问题

  1. 我想通过随机数删除第 1 行。
  2. 组中的第一行始终相同,并且始终位于相同的行号上。
  3. 该组的最后一行始终相同,但绝不会在同一行号上。
  4. 我已经得到了我想要的输出,但是我在将它写回同一个文件时遇到了问题。
  5. 我尝试了 -replace 和 set-content,但在这部分遇到了错误。

文件夹中的文本文件示例。

I want this deleted
here
here
here 
here
To here 

but i want this kept in file 1

文件 2

I want this deleted
here
here
here 
here
here
here
To here 

but i want this kept in file 2

以下是我想出的。

$files = Get-ChildItem 
Foreach-Object {

    #Targeting the specific file
    $keep = $true
    Get-Content $files | Where-Object { 
      if ( $_.StartsWith("I want this deleted")) {
        $keep = $false
      } elseif ( -not $keep -and $_.StartsWith("but") ) {
        $keep = $true
      }
      $keep
    } #End of where Object
  
}#End for Foreach loop

Output
but i want this kept in file 1
but i want this kept in file 2

【问题讨论】:

  • 用户选择字符串或正则表达式来获取文本并使用 -replace 'Target String'、'' 和 Set-Content cmdlet 或仅输出到新文件并存档/删除原始文件。
  • 我们还没有收到您的来信.. 任何给定的答案是否解决了您的问题?如果是这样,请通过单击左侧的 图标来考虑accepting。这将帮助其他有类似问题的人更轻松地找到它。

标签: powershell


【解决方案1】:

首先,您的示例 Foreach-Object 循环无效。你没有提供任何东西让它循环。您可以通过管道将文件传入或传递给-InputObject 参数。

接下来,当尝试写入时在管道中使用Get-Content 时,需要完全完成读取。确保这一点的一种简单方法是用括号括起来。

(Get-Content $files) | ...

但是,由于您要读取和写入不同的文件,这种方法是不正确的。您将使用上述命令从所有文件中收集内容。

最后,我建议不要排除你不想要的行,而只包括你想要的行。根据您的示例,您正在寻找以but 开头的行。我们可以使用 switch 语句来读取文件并处理行。我在这个例子中使用了正则表达式,但它也可以在没有正则表达式的情况下使用。

$files = Get-ChildItem 

$files | Foreach-Object {
    $output = Switch -Regex -File $_.fullname {
        'but' {$_}
    }
    $output | Set-Content $_.fullname
}#End for Foreach loop

这将一次读取每个文件,返回任何以 but 开头的行,捕获在 $output 变量中,最后我们将其写回同一个文件。

这是使用正则表达式的另一种方法

$files = Get-ChildItem 

$files | Foreach-Object {
    $output = Switch -File $_.fullname {
        {$_.startswith('but')} {$_}
    }
    $output | Set-Content $_.fullname
}#End for Foreach loop

【讨论】:

    【解决方案2】:

    你已经把事情复杂化了。新手也没关系,但请始终查看帮助文件和那里的示例,甚至是 Youtube 上的视频。

    所有这些都在 Powershell 帮助文件中。

    # Get specifics for a module, cmdlet, or function
    (Get-Command -Name Get-Help).Parameters
    (Get-Command -Name Get-Help).Parameters.Keys
    Get-help -Name Get-Help -Examples
    Get-help -Name Get-Help -Full
    Get-help -Name Get-Help -Online
    

    https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/set-content?view=powershell-7.1

    ***示例 3:*** 替换文件中的文本

    此命令替换现有文件中的所有单词实例。

    Get-Content -Path .\Notice.txt
    
    Warning
    Replace Warning with a new word.
    The word Warning was replaced.
    
    (Get-Content -Path .\Notice.txt) |
        ForEach-Object {$_ -Replace 'Warning', 'Caution'} |
            Set-Content -Path .\Notice.txt
    Get-Content -Path .\Notice.txt
    
    Caution
    Replace Caution with a new word.
    The word Caution was replaced.
    

    【讨论】:

      【解决方案3】:

      为了与您链接的代码保持一致,您可以对其进行调整以执行我认为您希望它执行的操作:

      # set the start and end lines for deletion here.
      # we will use the '-like' operator with a wildcard '*' appended, so these strings
      # should be at the start of the line to compare. (Case-Insensitive)
      $startDelete = 'I want this deleted'
      $stopDelete  = 'but i want this kept in file'
      
      # get a list of files that need updating and loop through
      # assuming all files have a '.txt' extension. If not, change that in the filter
      $files = Get-ChildItem -Path 'D:\Test' -Filter '*.txt' -File
      foreach ($file in $files) {
          Write-Host "Processing file $($file.FullName)"
          # set the $keep variable to $true to start off
          $keep = $true
          # collect every line we want to keep in a variable $content
          $content = Get-Content -Path $file.FullName | ForEach-Object {
              if ($_ -like "$startDelete*") {
                  # set the $keep variable to $false and do not output this line
                  $keep = $false
              }
              elseif ($_ -like "$stopDelete*") {
                  # set the $keep variable to $true so the line, 
                  # represented by automatic variable '$_' gets output
                  $keep = $true
              }
              # all lines are either blocked or output, depending on the value of $keep
              if ($keep) { $_ }
          }
      
          # we can now overwrite the original file with the new content
          Set-Content -Path $file.FullName -Value $content
      }
      

      我添加了代码 cmets 来帮助理解发生了什么

      【讨论】:

        猜你喜欢
        • 2013-10-10
        • 2015-06-23
        • 2015-05-18
        • 1970-01-01
        • 2014-08-11
        • 2013-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多