Powershell命令不起作用:从file2中删除file1中的行

时间:2017-06-17 19:38:30

标签: windows file windows-7 powershell-v2.0

我使用以下代码删除file1.txt中的file2.txt行。

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

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

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

2 个答案:

答案 0 :(得分:2)

补充LotPings' helpful answer

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

  • 对于内存效率,在通过管道发送之前,请不要先使用file1.txt收集$(...) 前面的所有行

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

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

哪个$是必要的,为什么?

(...) $(...) (子表达式运算符)和 @(...) array subexpression operator)所有数组中收集整个命令的/命令输出 ({{1除非输出仅包含 1 项,否则返回该项本身

[System.Object[]],只能包含单个命令或表达式:

  • 澄清表达式中的优先级,
  • 使用命令(cmdlet / function / external utility call)作为表达式的一部分。
  • 在管道中,您可以使用它来强制收集封闭命令的整个输出预先,但这样做会否定管道的内存限制优势。
    • 也就是说,使用类似(...)的内容可以“就地”更新给定文件(Get-Content file) | ... | Set-Content file - 但请注意,这需要file的全部内容适合内存。
  • 除非您有以下所述的其他要求,否则请file(...)$(...)
只需要{p> @(...)PetSerAl寻求帮助的提示。

  • 附上语句,例如$(...)if

  • 附上多个命令/表达式/语句

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

  • $(...) - 与$(...)不同 - 如果发生潜在终止错误,则不会中止整个命令; e.g:

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

hi只需要:

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

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

答案 1 :(得分:1)

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

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

Reference