我是一个寻求帮助的新手。我有一个包含两列数据的文本文件。一列是供应商,一列是发票。 我需要逐行扫描该文本文件,并查看路径中供应商和发票是否匹配。在路径$ Location中,第一个通配符是供应商编号,第二个通配符是Invoice 我希望非匹配输出到文本文件。
$Location = "I:\\Vendors\*\Invoices\*"
$txt = "C:\\Users\sbagford.RECOEQUIP\Desktop\AP.txt"
$Output ="I:\\Vendors\Missing\Missing.txt"
foreach ($line in Get-Content $txt) {
if (-not($line -match $location)){$line}
}
set-content $Output -value $Line
来自txt或csv文件的示例数据。
kvendnum wapinvoice
000953 90269211
000953 90238674
001072 11012016
002317 448668
002419 06123711
002419 06137343
002419 06134382
002419 759208
002419 753087
002419 753069
002419 762614
003138 N6009348
003138 N6009552
003138 N6009569
003138 N6009612
003182 770016
003182 768995
003182 06133429
在上面的数据中,唯一的匹配是在第二行:000953 90238674 和第6行:002419 06137343
答案 0 :(得分:0)
未经测试,但这是我接近它的方式:
$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