我有一个csv
,我从中返回一个哈希表:
Import-CSV "C:\rename.csv" | ForEach-Object { $Hash[$_.NUMBER] = $_.MY_ID + "." }
我想迭代一长串文件名。每当我在文件名中找到与NUMBER
的任何其他文件匹配时,我想创建一个日志条目:
Get-ChildItem "C:\files" | Foreach-Object {
# if a match on NUMBER is found, log:
# NUMBER,MY_ID,FILENAME >> log.txt
}
典型的文件名是(可以假设NUMBER
始终位于文件名中的第一个和第二个点之间):
dsadsadsa.343222.dsads23213jkjl.saddsa.pdf
dsadsadsa.123456.dsads23213jkjl.saddsa.pdf
dsadsadsa.111111.dsads23213jkjl.saddsa.pdf
dsadsadsa.33333333.dsads23213jkjl.saddsa.pdf
dsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf
典型的哈希值(来自csv)是(NUMBER
,MY_ID
):
123456,AB
121212,BB
33333333,CVV
因此,在这种情况下,我会找到123456
的1个匹配项和33333333
的2个匹配项。输出应该是一个日志文件,如下所示:
123456,AB,dsadsadsa.123456.dsads23213jkjl.saddsa.pdf
33333333,CVV,dsadsadsa.33333333.dsads23213jkjl.saddsa.pdf
33333333,dsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf
由于Hash表很大且文件数量也很多,所以我猜想代码只能通过dirlist运行。
任何人都可以帮助我根据哈希表匹配每个文件(每个NUMBER
可以有0个或更多匹配),并记录命中的文件吗?
非常感谢任何帮助。
答案 0 :(得分:2)
Regex::Escape
传递哈希键,因此我们可以安全地在正则表达式中使用它们key1|key2|...|keyN
换句话说:
$Hash = @{}
Import-CSV "C:\rename.csv" | ForEach-Object { $Hash[$_.NUMBER] = $_.MY_ID }
$escapedKeys = $Hash.Keys | ForEach-Object { [Regex]::Escape($_) }
$pattern = $escapedKeys -join "|"
Get-ChildItem "C:\files" | ForEach-Object {
$filename = $_.Name
$match = [Regex]::Match($filename, $pattern)
if ($match.Success) {
$NUMBER = $match.Value
$MY_ID = $Hash[$NUMBER]
"$NUMBER.$MY_ID.$filename"
}
} | Out-File log.txt
其他说明:
^(key1|key2|...|keyN)$
,以防止部分匹配。您可以将正则表达式模式编译为正确的Regex对象,如下所示:
$re = [Regex] $pattern
然后像这样使用它
$match = $re.Matches("z")
if ($match.Success) {
# etc
}
如果你有很多文件或很多密钥,这个可能提供速度优势。试试这对你有所帮助。
了解与Powershell匹配的正则表达式:http://www.regular-expressions.info/powershell.html