使用 PowerShell 从文本文件中删除多个特定行
Delete multiple, specific lines from text file using PowerShell
我正在使用 powershell 脚本来编辑从 registry.pol 生成的文本文件。最终目标是实现 CIS L1 基准。为了使 CIS L1 按照 this link 中的描述在 AWS EC2-image-builder 中工作,需要删除以下部分:
Computer
Software\Policies\Microsoft\Windows NT\Terminal Services
fPromptForPassword
DWORD:1
Computer
Software\Policies\Microsoft\WindowsFirewall\PublicProfile
AllowLocalPolicyMerge
DWORD:0
Computer
Software\Policies\Microsoft\WindowsFirewall\PublicProfile
AllowLocalIPsecPolicyMerge
DWORD:0
到目前为止,这是我的代码,用于将所有内容 但是 这 3 个部分传输到输出文件:
Get-Content -Path C:\MS-L1.txt -Raw | where -notmatch {
if( $_.StartsWith("Computer") ) {
$section = select-string -pattern Computer -context 0,3
if( ($section -like "fPromptForPassword") and ($section -like "AllowLocalPolicyMerge") and ($section -like "AllowLocalIPsecPolicyMerge") ){
}
} | Out-File c:\MS-L1.txt
我想弄清楚如何 select 某些第一行是“计算机”的部分,而不是 所有 第一行是“计算机”的部分,仅当“计算机”后面的行也匹配需要删除的内容时:
在一行中检查“计算机”
将当前行和接下来的 3 行存储为一个部分
检查唯一注册表设置部分(即 fPromptForPassword)
重复第 2 部分(从“计算机”开始)
重复第 3 部分“”
将剩余的(unselected)输出通过管道传输到 MS-L1.txt
我相信使用 -context 检查“computer”之后的 3 行是可行的,但我对我的嵌套 if 语句的格式没有信心,感谢您的指导!
由于您使用 Get-Content -Raw
来完整读取输入文件,因此使用单个 操作效率更高:
(Get-Content -Raw C:\MS-L1.txt) -replace '(?m)^Computer\r?\n.+\r?\n(?:fPromptForPassword|AllowLocalPolicyMerge|AllowLocalIPsecPolicyMerge)\r?\n.+(?:\r?\n)?'
注意:如果您知道自己总是在处理 CRLF 换行符(Windows 样式),则可以使用 \r\n
而不是 \r?\n
;如果你总是处理 LF 换行符(Unix 风格),\n
就可以了。
有关上面使用的正则表达式的解释,包括对其进行试验的能力,请参阅 this regex101.com page。
至于你试过的:
语法问题:
您的 Where-Object
(where
) command mixes simplified syntax 传递了 脚本块 ,这是不支持的;在摘要中你有两个选择:
简化语法:... | where someProperty -notmatch $someRegex
- 请注意,隐式操作输入对象 作为一个整体 而不是对其 属性之一 进行隐式操作 - 不幸的是 - 不支持PowerShell 7.2,但 GitHub issue #8357 建议在将来修复该问题。通过此增强功能,您可以执行
1..5 | Where -gt 2
之类的操作,但目前该操作失败。
脚本块语法:... | where { $_.someProperty -notmatch $someRegex }
概念问题:
您的命令被设计为 面向行的 (尽管您必须删除 -Raw
开关才能实际发送输入文件的通过管道 一条一条 行),因此您需要跟踪 Where-Object
脚本块中的多行以排除 块 行来自您的输入。
虽然直接使用 Select-String
及其 -NotMatch
开关原则上提供 excluding 匹配行,但您不能有意义地将其与-Context
参数,因为作为上下文捕获的其他行 不受此排除的影响 。
我正在使用 powershell 脚本来编辑从 registry.pol 生成的文本文件。最终目标是实现 CIS L1 基准。为了使 CIS L1 按照 this link 中的描述在 AWS EC2-image-builder 中工作,需要删除以下部分:
Computer
Software\Policies\Microsoft\Windows NT\Terminal Services
fPromptForPassword
DWORD:1
Computer
Software\Policies\Microsoft\WindowsFirewall\PublicProfile
AllowLocalPolicyMerge
DWORD:0
Computer
Software\Policies\Microsoft\WindowsFirewall\PublicProfile
AllowLocalIPsecPolicyMerge
DWORD:0
到目前为止,这是我的代码,用于将所有内容 但是 这 3 个部分传输到输出文件:
Get-Content -Path C:\MS-L1.txt -Raw | where -notmatch {
if( $_.StartsWith("Computer") ) {
$section = select-string -pattern Computer -context 0,3
if( ($section -like "fPromptForPassword") and ($section -like "AllowLocalPolicyMerge") and ($section -like "AllowLocalIPsecPolicyMerge") ){
}
} | Out-File c:\MS-L1.txt
我想弄清楚如何 select 某些第一行是“计算机”的部分,而不是 所有 第一行是“计算机”的部分,仅当“计算机”后面的行也匹配需要删除的内容时:
在一行中检查“计算机”
将当前行和接下来的 3 行存储为一个部分
检查唯一注册表设置部分(即 fPromptForPassword)
重复第 2 部分(从“计算机”开始)
重复第 3 部分“”
将剩余的(unselected)输出通过管道传输到 MS-L1.txt
我相信使用 -context 检查“computer”之后的 3 行是可行的,但我对我的嵌套 if 语句的格式没有信心,感谢您的指导!
由于您使用 Get-Content -Raw
来完整读取输入文件,因此使用单个
(Get-Content -Raw C:\MS-L1.txt) -replace '(?m)^Computer\r?\n.+\r?\n(?:fPromptForPassword|AllowLocalPolicyMerge|AllowLocalIPsecPolicyMerge)\r?\n.+(?:\r?\n)?'
注意:如果您知道自己总是在处理 CRLF 换行符(Windows 样式),则可以使用 \r\n
而不是 \r?\n
;如果你总是处理 LF 换行符(Unix 风格),\n
就可以了。
有关上面使用的正则表达式的解释,包括对其进行试验的能力,请参阅 this regex101.com page。
至于你试过的:
语法问题:
您的 Where-Object
(where
) command mixes simplified syntax 传递了 脚本块 ,这是不支持的;在摘要中你有两个选择:
简化语法:
... | where someProperty -notmatch $someRegex
- 请注意,隐式操作输入对象 作为一个整体 而不是对其 属性之一 进行隐式操作 - 不幸的是 - 不支持PowerShell 7.2,但 GitHub issue #8357 建议在将来修复该问题。通过此增强功能,您可以执行
1..5 | Where -gt 2
之类的操作,但目前该操作失败。
- 请注意,隐式操作输入对象 作为一个整体 而不是对其 属性之一 进行隐式操作 - 不幸的是 - 不支持PowerShell 7.2,但 GitHub issue #8357 建议在将来修复该问题。通过此增强功能,您可以执行
脚本块语法:
... | where { $_.someProperty -notmatch $someRegex }
概念问题:
您的命令被设计为 面向行的 (尽管您必须删除
-Raw
开关才能实际发送输入文件的通过管道 一条一条 行),因此您需要跟踪Where-Object
脚本块中的多行以排除 块 行来自您的输入。虽然直接使用
Select-String
及其-NotMatch
开关原则上提供 excluding 匹配行,但您不能有意义地将其与-Context
参数,因为作为上下文捕获的其他行 不受此排除的影响 。