我正在尝试查找文件夹中与数组中的任何条目匹配的所有文件,以便我可以将它们移动到另一个文件以用于组织。我可以在这里使用PowerShell 2.0;我不确定这是不是让我失望,我在学校学习了PowerShell 4.0。
# Declared variables & array
$files = get-childitem "Y:\Downloads\"
$start = "Y:\Downloads\"
$end = "Y:\Downloads\sorted"
$fileEXT = "*.jokes.*","*.laughter.*","*.comedy.*","*.humour.*"
# Moving Files
#foreach ($file in $files) {
# if ($file.Name -contains $fileEXT[0-9]) {
# Move-Item $start $end
# }
#}
foreach ($element in $fileEXT) {
if ($files.Name -contains $element) {
Move-Item $start $end
}
}
#$start | Where-Object { $fileEXT -contains $_.Name } | Move-Item to $end
答案 0 :(得分:0)
试试这个(别忘了删除-whatif)
注意:
- $_.Base contains file name without extension
- use !$_.PSIsContainer for take only files
代码:
$fileEXT = "test","laughter","comedy","humour"
$start = "Y:\Downloads\"
$end = "Y:\Downloads\sorted"
#solution 1
Get-ChildItem $start | where {$Name=$_.BaseName; !$_.psiscontainer -and ($fileEXT | where {$name -like "*$_*"}).Count -gt 0 } |
move-item -Destination $end -WhatIf
#solution 1b (powershell 3)
Get-ChildItem $start -file | where {$Name=$_.BaseName; ($fileEXT | where {$name -like "*$_*"}).Count -gt 0 } |
move-item -Destination $end -WhatIf
#Solution 2 with regex
$fileEXT = "test|laughter|comedy|humour"
Get-ChildItem $start | where {!$_.psiscontainer -and $_.BaseName -match $fileEXT} |
move-item -Destination $end -WhatIf
#Solution 2b with regex (powershell 3), better solution gived by @TessellatingHeckler
$fileEXT = "test|laughter|comedy|humour"
Get-ChildItem $start -file | where { $_.BaseName -match $fileEXT} |
move-item -Destination $end -WhatIf
答案 1 :(得分:0)
与提到的@BenH一样,您使用的是错误的运算符。 -contains
运算符允许您检查数组是否包含特定值(不是值的一部分):
'ab', 'cd', 'ef' -contains 'cd' # returns true
'ab', 'cd', 'ef' -contains 'c' # returns false
您可能会将运算符与String.Contains()
方法混淆,后者允许您检查字符串是否包含特定的子字符串:
'abcdef'.Contains('cd')
但是,它们都不允许检查字符串是否包含任何子字符串列表。您的方法需要两个循环,因为您需要将每个文件与每个过滤器元素进行比较,并且需要使用-like
运算符进行通配符比较。来自内循环的Break因此,如果项目与多个过滤元素匹配,则不要尝试移动项目两次。
foreach ($file in $files) {
foreach ($element in $fileEXT){
if ($file.Name -like $element){
Move-Item $file.FullName $end
break
}
}
}
但是,使用嵌套循环将两个数组相互比较并不会很好。更好的方法是将搜索项放在数组中并从中构造regular expression,这样就可以一次性检查所有过滤元素:
$words = 'jokes', 'laughter', 'comedy', 'humour'
$re = '\.(' + ($words -join '|') + ')\.'
Get-ChildItem 'Y:\Downloads' |
Where-Object { $_.Name -match $re } |
Move-Item -Destination 'Y:\Downloads\sorted'
作为旁注,虽然您可以使用单个字符串定义正则表达式,但我不建议这样做。除非你打算这是一个一次性的脚本(也许甚至不是那样)。
$re = '\.(jokes|laughter|comedy|humour)\.' # don't do this
使$words
数组并加入数组以形成实际的正则表达式使维护更容易,并允许您将单词放在单独的文件中(与代码分开的数据):
jokes laughter comedy humour
让你的脚本读取该文件:
$words = Get-Content 'C:\wordlist.txt'