Organizing files by type
I have this script which runs periodically to collect desktop files and organizes them by the file type into a single folder on backup drive.
function get-destbytype($ext)
{
switch ($ext)
{
{ $ext -match '(jpg|png|gif|bmp)'} { "images" }
{ $ext -match '(divx|mpeg|avi)'} { "videos" }
{ $ext -match '(cs|js|java|py|class|vbs|jsp开发者_StackOverflow社区)'} { "code" }
{ $ext -match '(sql|ps1|pl|py)'} { "scripts" }
{ $ext -match '(zip|7z|rar)'} { "compressed" }
{ $ext -match '(ppt|pptx|doc|docx|pdf)'} { "documents" }
{ $ext -match '(csv|xls|xlsx)'} { "spreadsheets" }
{ $ext -match '(exe|dll|jar|ear|bat|cmd)'} { "executables" }
{ $ext -match '(txt|log)'} { "text" }
{ $ext -match '(msg|htm|html|lnk)'} { "miscellaneous" }
{ $ext -match '(properties|xml|ini)'} { "config" }
default {"$ext" }
}
}
$dirtyfolder = "C:\Documents and Settings\user\Desktop\"
$org = "$nas\Desktop\ORG"
ls $dirtyfolder/* | ? {!$_.PSIsContainer} | %{
$dest = "$($org)\$(get-destbytype $_.extension)"
if (! (Test-Path -path $dest ) )
{
write-host "creating $dest"
new-item $dest -type directory
}
mv -path $_ -destination $dest
}
The script was tested thoroughly and seems to run fine in most cases I could imagine. Recently when .csv
files were encountered for the first time, they were moved into a new folder by the name
code spreadsheets
.
This is obviously because the .cs
files are supposed to go to the code
folder and the .csv
files to the spreadsheets
folder, and the script does not distinguish between .cs
and .csv
.
How do I modify the script to not do this?
Also what can be done to exclude desktop shortcuts with extension .lnk
?
Try using a more specific regular expression. Just add $ signs at the end of your expressions. The $ sign indicates end of line or in your case end of string.
It would look like this:
{ $ext -match '(jpg|png|gif|bmp)$'} { "images" }
You can easily test this by opening powershell and typing:
"abc.csv" -match '(cs|xls)$'
This will result in False.
Another best practice is to add a break statement at the end of each condition. That is, when a match is found all other conditions are not tested. It will also make the comparison faster.
{ $ext -match '(jpg|png|gif|bmp)$'} { "images"; break}
The more specific regex is one possible solution. A more processor-friendly one is to order your switch statement from most to least specific, and include a 'break' directive after each case. In this way, when you match "csv" it will quit evaluating the other cases.
Your erroneous output is a result of both cases matching and both values being returned. The tighter regex causes only one case to match, but you're still evaluating every element when you probably neither meant nor realized this would happen. Using the break directive on each case is one more way to be less ambiguous and save a couple cycles.
You can add an exception for shortcuts in the parameters for ls.
ls $dirtyfolder/* | ? {(!$_.PSIsContainer) -and !($_.extension -eq ".lnk")}
精彩评论