我有一个包含几行的文本文件:
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
- 匹配下面的正则表达式(如果这个失败则尝试下一个替代方案)«^.»
- 断言字符串“^”开头的位置
- 匹配任何不是换行符“。”的单个字符
- 或者匹配下面的 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.+$'}