【问题标题】:Powershell script to remove line of text from files in folderPowershell脚本从文件夹中的文件中删除文本行
【发布时间】:2018-04-28 17:49:18
【问题描述】:

我们有一个程序可以创建电子邮件签名并将其存储在部署文件夹中,然后在用户登录时将其保存到用户本地文件夹中。但是,当员工未分配到办公室时,城市/州的逗号分隔符仍如本例所示顺路顺风顺水:

Example Email signature

问题是找不到程序源代码。长期我会重写它。短期内我需要一个每晚运行的powershell脚本来删除包含逗号的行。在 Stackoverflow 上找到以下解决方案:

Get-ChildItem C:\temp\emailsigs -Filter *.htm | Foreach-Object{
(Get-Content $_.FullName) | 
Foreach-Object {$_ -replace " ,   &nbsp; ,   &nbsp; <br />", ""} | 
Set-Content $_.FullName
}

这实际上效果很好。但我注意到每个签名 HTM 文件(超过 1100 个)都在获取时间戳更新,即使只有 2 个电子邮件签名需要删除空逗号行。有没有更有效的方法来首先检查文件是否包含有问题的逗号,然后替换并跳过大部分?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    以下 PSv5+ 解决方案不会节省内存,但应该加快处理速度,同时避免重写不需要的文件:

    Get-ChildItem C:\temp\emailsigs -Filter *.htm |
      ForEach-Object {
        $oldContent = Get-Content -Raw $_.FullName
        $newContent = $oldContent -replace ' ,   &nbsp; ,   &nbsp; <br />'
        if ($newContent.Length -lt $oldContent.Length) { # was a replacement performed?
          Set-Content $_.FullName -NoNewline -Value $newContent
        }
      }
    
    • -Raw 是 PSv3+,将整个文件作为单个字符串读取。

      • 在 PSv2 中,您可以改用 [System.IO.File]::ReadAllText(),但请注意,在没有 BOM 的情况下,它假定 UTF-8 作为编码,而 Get-Content 假定“ANSI”编码[1] (系统的旧版“ANSI”代码页),因此您可能必须明确指定编码。
    • 将每个文件作为单个字符串处理会加快处理速度(尽管每个文件必须两次装入内存)。如果正则表达式不匹配,利用-replace 保留未修改的输入字符串,我们可以将原始内容的长度与替换内容的长度进行比较,以查看是否匹配,因此文件需要重写。
      因此,每个文件我们只需要一个正则表达式操作。

      • 另请注意,... -replace '...' - 即不指定 替换 字符串 - 等效于 ... -replace '...', '',即有效地删除匹配的内容。李>
    • -NoNewline 需要 PSv5+;它可以防止 additional 换行符被附加到输出中。

      • 在 PSv4- 中,您可以改用 [System.IO.File]::WriteAllText(),但请注意,它的默认编码是 UTF-8没有 BOM,而 Set-Content,如 Get-Content,默认为“ANSI " 编码[1].

    [1] 以上适用于 Windows PowerShell。跨平台的PowerShell Core 版本也默认为(BOM-less)UTF-8。

    【讨论】:

    • 我确认 htm 文件没有被其他程序使用。我怀疑这个脚本进程保持文件锁定。所以我不得不授予第二个解决方案,因为它有效。
    • @user3195770:是的,正是我的原始答案中的Get-Content 使每个输入文件保持锁定状态,防止其被替换。但是,我几个小时前发布的修订版通过使用Get-ChildItem 避免了这个问题。它仍然具有仅匹配文件内容 once 的优点,并且由于将文件作为单个字符串处理而通常更快(另外,我刚刚添加了另一个优化以仅比较内容 length i> 确定是否进行了更换)。
    • 酷,我将尝试测试几个。希望我能奖励两个答案。
    • @user3195770:理解:一般来说,如果多个答案同样地解决了您的问题(希望不是以完全相同的方式,因为这会使它们重复),我建议接受一个最有可能帮助未来读者的答案.为了表达对其他人的感激之情,您通常会投票给他们,但还没有足够的声誉(需要 >= 15)。
    【解决方案2】:

    其他方法

    Get-ChildItem C:\temp\emailsigs -file -Filter *.htm | foreach{
    
    $CurrentFile=$_
    
    $Content=Get-Content $CurrentFile.FullName -Encoding UTF8
    
    if ($Content -like '* ,   &nbsp; ,   &nbsp; <br />*')
    {
        $Content.Replace(' ,   &nbsp; ,   &nbsp; <br />', '') | Set-Content $CurrentFile.FullName -Encoding UTF8
    }
    
    }
    

    我使用 utf8 来保留变音符号

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 2019-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-06
      • 1970-01-01
      相关资源
      最近更新 更多