批处理文件中的 Powershell 命令:从文本文件中删除除“foo”和“bar”行之外的所有行?

批处理文件中的 Powershell 命令:从文本文件中删除除“foo”和“bar”行之外的所有行?

我有一个包含以下三行的文本文件:

This line contains foo.
This line contains bar.
This line has neither.

我可以在“.bat”文件(上面的“.txt”文件旁边)中运行以下命令,它会删除文本文件中除包含“foo”的行之外的所有行:

Powershell.exe -Command "gci *.txt | foreach { (cat $_.FullName | ? { $_ -like '*foo*' }) | set-content $_.FullName}"

运行该程序可获得预期效果,文本文件中仅保留此行:

This line contains foo.

现在的问题是:如果我想保留包含“foo”的行怎么办行中的“bar”?

到目前为止,我可能已经尝试了 40 或 50 种不同的组合,放置管道字符:*foo*|*bar*、去掉星号foo|bar、仅在开始和结尾放置星号:*foo|bar*、使用逗号、不使用逗号、使用分号、不使用分号、使用和-like不使用分号重复命令$_ 以及许多其他方法。

什么都不起作用——到目前为止,每次尝试,我最终得到的文本文件都是一样的,原始三行包含 foo(第 1 行)、bar(第 2 行)和两者都不包含(第 3 行)。

为了确保我没有编辑命令并犯错误,我会定期删除我的编辑并再次运行命令,只需删除行中没有“foo”的行即可,或者我只是再次粘贴命令,再次测试它,然后开始尝试编辑它以包含“bar”,但无济于事。

我最近已经问过这个问题了,但我想我的标题措辞不够清楚。有人试图回答这个问题,但他们提供的每个答案都没有用,至少当我将命令放入批处理文件中并在文本文件旁边运行时,也许这对他们有用,使用的方法与我的方法不同,我不知道。

请注意,我在批处理文件中使用了 powershell 命令!我没有在控制台中输入内容或使用 ps1 脚本。 我不需要做任何这些,因为我上面提到的第一个命令确实有效删除所有带有“foo”的行。

显然,由于它确实有效,因此可以将其作为基础进行添加,这样它就可以在一个命令中处理“foo”和“bar”。

当然,除非这 100% 不可能——经过大约 4 天的尝试,我对命令进行了 40 或 50 种不同的变化后,我开始怀疑这一点!

如果有人回答这个问题,请发布一个批处理文件命令,就像我上面那样。请不要告诉我切换到使用 ps1 脚本或给出解释在控制台窗口中输入什么的答案。

我上面发布的命令只需要进行某种修改,以便可以将“bar”添加到“foo”,这样它就可以处理多个文本字符串。

之所以如此困难,似乎是因为如果您运行命令删除除“foo”之外的所有行,那么您已经删除了“bar”行。我怀疑这就是为什么没有人想出可行的解决方案,也许根本就没有解决方案。

在此先感谢所有能给出有效答案的人。通常这些问题在这里都能很快得到解答,或者我只是不断尝试不同的方法,然后就能解决问题 - 但这次不行,出于某种原因,这是一个非常棘手的问题。

答案1

只需使用以 OR 连接的两个单独条件即可:

cat $_.FullName | ? { $_ -like '*foo*' -or $_ -like '*bar*' }

可以使用括号来增加清晰度,但它们是可选的:

{ ($_ -like '*foo*') -or ($_ -like '*bar*') }

发布一个批处理文件命令,就像我上面那样。请不要告诉我切换到使用 ps1 脚本或给出解释在控制台窗口中输入什么的答案。

它们是完全相同的。无论你如何调用 PowerShell 脚本 - 无论它是存储在文件中、通过命令行传递还是通过键盘输入,它仍然是 PowerShell 脚本,并且遵循相同的语法规则。

答案2

您可以改用select-string采用正则表达式的方法:

gci *.txt | % { (cat $_.FullName | select-string -pattern 'foo|bar') | set-content $_.FullName -Force }

select-string如果需要,允许您执行更复杂的正则表达式匹配。


进一步阅读

相关内容