Powershell-从每行删除20个字符

Powershell-从每行删除20个字符

我有一个包含几行的文本文件:

9 1/7/20 11:46:25 am PC-OCWIN0306 Device status is Critical. Protection is off.

10 1/7/20 11:10:16 am PC-OCWIN0277 Device status is Critical. Protection is off; Security application is not running.

11 1/7/20 2:47:19 pm LT-FRWIN0004 Device status is Critical. Security application is not installed.

我想删除每行的前 20 个字符,因此它看起来像:

PC-OCWIN0306 Device status is Critical. Protection is off.
PC-OCWIN0277 Device status is Critical. Protection is off; Security application is not running.
LT-FRWIN0004 Device status is Critical. Security application is not installed.

我一直在尝试使用这个:

$testfile = Get-Content -Path "Z:\IT Users\Username\test.txt"
foreach($line in $testfile) {
    $line.TrimStart(20)
    }
}
Out-File "Z:\IT Users\Username\trimtest.txt"
pause

但它没有达到我想要的效果。

答案1

Windows 10 64 位。PowerShell 5

使用 PowerShell 和正则表达式从命令行编辑文本文件。

通过用空替换删除从行首到模式“m”的部分。删除多余的回车符和多余的换行符(将双倍行距改为单倍行距)。

$source  = "$env:userprofile\Desktop\2.txt" 
$trim = "$env:userprofile\Desktop\3.txt" 
(Get-Content $source -Raw) -replace "^.|.*m " -replace "[`r`n]+", "`n" | Set-Content $trim

生的,回车符和换行符在 stackoverflow 上的解释

  • 默认情况下,get-content 会自动按换行符将文件拆分为多行。您需要使用 -raw 参数将文件读取为单个文本块。

https://regex101.com测试您的正则表达式并了解它们的工作原理。对于这种替换方法,我发现工具 - 代码生成器 - 语言 - AutoIt 很有用。

正则表达式:^.|.*m 不要忘记 m 后面的空格。从行首开始匹配直到模式“m”的所有内容。

正则表达式:(?m) D.*.$匹配“D”之后的所有内容,除回车符和换行符之外。

正则表达式:[\r\n]+将双倍行距改为单倍行距。

测试文件/字符串:

9 1/7/20 11:46:25 am PC-OCWIN0306 Device status is Critical. Protection is off.

10 1/7/20 11:10:16 am PC-OCWIN0277 Device status is Critical. Protection is off; Security application is not running.

11 1/7/20 2:47:19 pm LT-FRWIN0004 Device status is Critical. Security application is not installed.

结果:

PC-OCWIN0306 Device status is Critical. Protection is off.    
PC-OCWIN0277 Device status is Critical. Protection is off; Security application is not running.    
LT-FRWIN0004 Device status is Critical. Security application is not installed.

替换除设备名称之外的所有内容:

$source  = "$env:userprofile\Desktop\2.txt" 
$trim = "$env:userprofile\Desktop\3.txt" 
(Get-Content $source -Raw) -replace "^.|.*m " -replace "(?m) D.*.$" -replace "[`r`n]+", "`n" | Set-Content $trim

结果:

PC-OCWIN0306
PC-OCWIN0277
LT-FRWIN0004 

谢谢https://regex101.com/查看屏幕截图。

正则表达式 ^.|.*m 的屏幕截图

正则表达式 (?m) D.*.$ 的屏幕截图

正则表达式 \r\n 的屏幕截图

^.|.*m

  • 匹配下面的正则表达式(如果这个失败则尝试下一个替代方案)«^.»
    • 断言字符串“^”开头的位置
    • 匹配任何不是换行符“。”的单个字符
  • 或者匹配下面的 2 号正则表达式(如果这个正则表达式匹配失败,则整个匹配尝试失败)«.*m »
    • 匹配任何不是换行符“.*”的单个字符
      • 在零次至无限次之间,尽可能多次,根据需要回馈(贪婪)«*»
    • 匹配字符“m”按字面意思为“m”

(?米)D.*.$

  • 使用以下选项匹配正则表达式的其余部分:^ 和 $ 在换行符处匹配(m)
  • 逐字匹配字符“ D”
  • 匹配任何不是换行符的单个字符
    • 在零次至无限次之间,尽可能多次,根据需要回馈(贪婪)
  • 匹配任何不是换行符的单个字符
  • 断言行末的位置(在字符串末尾或换行符之前)

[\r\n]+

  • 匹配下面列表中的单个字符
    • 一次至无限次之间,尽可能多次,根据需要回馈(贪婪)
    • 回车符
    • 换行符(新行)

使用 PS 和 Regex 编辑文本文件。使用 PowerShell 和 Regex 编辑文本文件。使用 PowerShell 和正则表达式编辑文本文件。

答案2

你想要消除方法。

$testfile = Get-Content -Path "Z:\IT Users\Username\test.txt"
foreach($line in $testfile) {
    $line.Remove(0,20)
    }
} | Out-File "Z:\IT Users\Username\trimtest.txt"

或者避免中间变量:

Get-Content -Path "Z:\IT Users\Username\test.txt" | ForEach{
   $_.Remove(0,20)
} | Out-File "Z:\IT Users\Username\trimtest.txt"

编辑:我相信了你关于 20 个字符的说法,但请注意日期/时间的长度可能会有所不同,如果是这样,正则表达式是你最好的选择。你的输入文件是否真的在每行文本之间包含空行?如果没有,以下正则表达式应该可以解决问题,而且更容易看到它捕获的内容:

Get-Content $source | ForEach{$_ -replace '^.+m ' -replace ' Device.+$'}

相关内容