未经测试,但这是我的处理方法:
$Location = "I:\\Vendors\\.+\\Invoices\\.+"
$txt = "C:\\Users\sbagford.RECOEQUIP\Desktop\AP.txt"
$Output ="I:\\Vendors\Missing\Missing.txt"
select-string -path $txt -pattern $Location -notMatch |
set-content $Output
无需逐行浏览文件; PowerShell 可以使用select-string 为您执行此操作。 -notMatch 参数只是反转搜索并通过与模式不匹配的任何行发送。
select-string 发送一个matchinfo 对象流,其中包含满足搜索条件的行。这些对象实际上包含比匹配行更多的信息,但幸运的是 PowerShell 足够聪明,知道如何将相关项目发送到 set-content。
正则表达式可能很难正确处理,但如果您要执行此类任务,则值得一试。
编辑
$Location = "I:\Vendors\{0}\Invoices\{1}.pdf"
$txt = "C:\\Users\sbagford.RECOEQUIP\Desktop\AP.txt"
$Output = "I:\Vendors\Missing\Missing.txt"
get-content -path $txt |
% {
# extract fields from the line
$lineItems = $_ -split " "
# construct path based on fields from the line
$testPath = $Location -f $lineItems[0], $lineItems[1]
# for debugging purposes
write-host ( "Line:'{0}' Path:'{1}'" -f $_, $testPath )
# test for existence of the path; ignore errors
if ( -not ( get-item -path $testPath -ErrorAction SilentlyContinue ) ) {
# path does not exist, so write the line to pipeline
write-output $_
}
} |
Set-Content -Path $Output
我想我们最终将不得不逐行挑选文件。如果有更惯用的方法来做到这一点,那我就不知道了。
上面的代码假定输入文件中的格式一致,并使用-split 将行分成一个数组。
编辑 - 版本 3
$Location = "I:\Vendors\{0}\Invoices\{1}.pdf"
$txt = "C:\\Users\sbagford.RECOEQUIP\Desktop\AP.txt"
$Output = "I:\Vendors\Missing\Missing.txt"
get-content -path $txt |
select-string "(\S+)\s+(\S+)" |
%{
# pull vendor and invoice numbers from matchinfo
$vendor = $_.matches[0].groups[1]
$invoice = $_.matches[0].groups[2]
# construct path
$testPath = $Location -f $vendor, $invoice
# for debugging purposes
write-host ( "Line:'{0}' Path:'{1}'" -f $_.line, $testPath )
# test for existence of the path; ignore errors
if ( -not ( get-item -path $testPath -ErrorAction SilentlyContinue ) ) {
# path does not exist, so write the line to pipeline
write-output $_
}
} |
Set-Content -Path $Output
似乎-split " " 在运行脚本中的行为与其在命令行中的行为不同。诡异的。无论如何,这个版本使用正则表达式来解析输入行。我根据原始帖子中的示例数据对其进行了测试,它似乎有效。
正则表达式分解如下
( Start the first matching group
\S+ Greedily match one or more non-white-space characters
) End the first matching group
\s+ Greedily match one or more white-space characters
( Start the second matching group
\S+ Greedily match one or more non-white-space characters
) End the second matching groups