簡體   English   中英

PowerShell逐行讀取文本文件並在文件夾中查找丟失的文件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM