[英]PowerShell read text file line by line and find missing file in folders
我是新手,需要一些帮助。 我有一个包含两列数据的文本文件。 一栏是供应商,一栏是发票。 我需要逐行扫描该文本文件,并查看路径中的供应商和发票是否匹配。 在路径$ Location中,第一个通配符是供应商编号,第二个通配符是发票,我希望将不匹配项输出到文本文件。
$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和第六行:002419 06137343
未经测试,但是这是我的处理方法:
$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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.