Powershell 命令不起作用:从文件 1 中删除文件 2 中的行

Powershell command not working: removing lines from file1 that are in file2

我正在使用以下代码从 file1.txt 中删除 file2.txt.

中的行
powershell -Command "$(Get-Content file1.txt) | Where-Object {$_ -notIn $(Get-Content file2.txt)}"

但我收到有关 -notIn 的错误,正在查找值表达式。但是 file2.txt 确实存在并且不为空。

导致错误的原因是什么,如何解决?

对于 PowerShell v2,反转参数并使用 -NotContains

powershell -Command "$(Get-Content file1.txt) | Where-Object {$(Get-Content file2.txt) -NotContains $_ }

Reference

补充

  • 为了执行速度,不要在每次循环迭代中执行Get-Content file2.txt - 缓存其结果事先.

  • 为了内存效率,不要收集file1.txt预先的所有行$(...) 在通过管道发送它们之前。

因此(为简洁起见,我省略了 powershell -Command "..." 包装器):

$f2 = Get-Content file2.txt; Get-Content file1.txt | Where-Object { $f2 -NotContains $_ }

Which $ are necessary, and why?

(...)$(...)(子表达式运算符)和 @(...)数组子表达式运算符)所有收集整个命令的/命令的输出作为一个整体 ,在 array ([System.Object[]]) 中,除非输出仅包含 1 项目,其中该项目本身返回。

需要

(...),它只能包含一个单个命令或表达式:

  • 为了阐明表达式中的优先级,
  • 将命令(cmdlet/函数/外部实用程序调用)用作表达式的一部分。
  • 在管道中,您可以使用它强制收集封闭命令的整个输出预先,但这样做会抵消管道的内存限制优势。
    • 也就是说,使用 (Get-Content file) | ... | Set-Content file 之类的东西可以更新给定的文件 file "in-place" - 但请注意,这需要 file 的全部内容才能适应内存。
  • 除非您有如下所述的额外要求,否则首选 (...) 而不是 $(...)@(...)

$(...) 只需要:PetSerAl 致敬。

  • 来包含语句,例如ifforeach

  • 圈出多个commands/expressions/statements

  • 将上面的嵌入到"..."中(一个双引号字符串,其内容受到插值(扩展))。
    在列出的运算符中,$(...) 只有 可以(直接)嵌入双引号字符串中的运算符。

  • $(...) - 与 (...) 不同 - 如果发生 可能终止 错误,则不会中止整个命令;例如:

    • 'hi' + $(1/0)"hi$(1/0)" 报告被零除错误,但仍然打印 hi;相比之下,'hi' + (1/0) 不会 - 除零错误会中止整个表达式。
    • 请注意,无条件终止 错误甚至会中止任何包含 $(...) 的表达式;例如,'hi' + $(Throw 'err')"hi$(Throw 'err')" 都只打印错误消息,而不是 hi.

@(...)只需要:

  • 确保命令的输出是一个数组,即使只返回1项;在其他方面,它的作用类似于 $(),只是您不能在 "..." 中使用它;有关 @() 的详细讨论,请参阅我的

  • 在 PSv3+ 中,标量和数组的统一处理 通常 使得 @(...) 变得不必要,但是 - 请参阅我的