テストされていないが、ここで私はそれにアプローチしたい方法は次のとおりです。
$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
ファイルを1行ずつ選ぶ必要はありません。 PowerShellはselect-string
を使用してこれを行うことができます。 -notMatch
パラメータは検索を単に反転し、パターンに一致しない行を送信します。
select-string
は、検索条件を満たす行を含むmatchinfo
オブジェクトのストリームを送信します。これらのオブジェクトには、実際には一致する行だけの情報が含まれていますが、幸いPowerShellはスマートで、関連する項目をset-content
に送信する方法を知っています。
正規表現は正しく動作するようにすることはできますが、このような作業を行う場合は頭を下げる価値があります。
EDIT
$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
を使用して行を配列に分割します。
EDIT - バージョン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 " "
が、それはコマンドライン上でどのように動作するかを実行しているスクリプトで異なる挙動ようでした。奇妙な。とにかく、このバージョンでは正規表現を使って入力行を解析します。元の投稿のサンプルデータと比較してテストしたところ、うまくいくように見えました。
あなたは正規表現を期待している-match演算子とワイルドカードの構文を使用している
( 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
を次のように正規表現が破壊されます。ワイルドカードを使用した場合は、ワイルドカードを使用します。 – mjolinor