我使用以下代码删除file1.txt
中的file2.txt
行。
powershell -Command "$(Get-Content file1.txt) | Where-Object {$_ -notIn $(Get-Content file2.txt)}"
但我收到关于-notIn的错误,正在查找值表达式。但file2.txt
确实存在且不为空。
导致错误的原因是什么,以及如何解决?
答案 0 :(得分:2)
对于执行速度,不要在每次循环迭代中执行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[]]
,只能包含单个命令或表达式:
(...)
的内容可以“就地”更新给定文件(Get-Content file) | ... | Set-Content file
- 但请注意,这需要file
的全部内容适合内存。 file
至(...)
和$(...)
。@(...)
:向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 $_ }