4

I have a cleanup script that moves files based on their extension to appropriate preset locations.

For example, a file with the extension .xls will be moved to ~\XLS folder, .sql to ~\SQL and so on. Here is the my script.

$dirtyfolder = "\\server\c$\Documents and Settings\user\Desktop\"
$org = "\\BACKUPS\users\"
dir $dirtyfolder -fil *.doc | mv -dest "$($org)ORG\doc"
dir $dirtyfolder -fil *.txt | mv -dest "$($org)ORG\txt"
dir $dirtyfolder -fil *.sql | mv -dest "$($org)ORG\sql"
dir $dirtyfolder -fil *.log | mv -dest "$($org)ORG\log"
dir $dirtyfolder -fil *.zip | mv -dest "$($org)ORG\zip"
dir $dirtyfolder -fil *.7z | mv -dest "$($org)ORG\zip"
dir $dirtyfolder -fil *.png | mv -dest "$($org)ORG\img"
dir $dirtyfolder -fil *.jpg | mv -dest "$($org)ORG\img"
dir $dirtyfolder -fil *.mp3 | mv -dest "$($org)ORG\mp3"

I am fully aware that this in an inelegant way to achieve my objective. So I would like to know how I can modify the script so that I can

  1. reuse repetitive code
  2. if the destination folder does not exist, it should be created.
  3. group similar extensions, like png and jpg
Ben
  • 51,770
  • 36
  • 127
  • 149
Animesh
  • 4,926
  • 14
  • 68
  • 110

2 Answers2

5

Tested. A (not-recursive) solution that does not manage grouping:

ls $dirtyfolder/* | ? {!$_.PSIsContainer} | %{
  $dest = "$($org)ORG\$($_.extension)"
  if (! (Test-Path -path $dest ) ) {
    new-item $dest -type directory
  }
  mv -path $_.fullname -destination $dest 
}

Solution with grouping:

ls $dirtyfolder/* | ? {!$_.PSIsContainer} | %{
  $dest = "$($org)ORG\$(get-destbytype $_.extension)"
  if (! (Test-Path -path $dest ) ) {
    new-item $dest -type directory
  }
  mv -path $_.fullname -destination $dest 
}

where get-destbytype is the following function:

function get-destbytype($ext) {
 Switch ($ext)
 {
  {$ext -match '(jpg|png|gif)'} { "images" }
  {$ext -match '(sql|ps1)'} { "scripts" }
  default {"$ext" }
 }
}
Emiliano Poggi
  • 24,390
  • 8
  • 55
  • 67
  • I have tested the non-grouping solution and it worked well for me. I will test the grouping solution and will let you know. Thanks. :-) – Animesh May 02 '11 at 18:58
  • +1. Very cool :) Just one question. Is there any reason to use ls "$($dirtyfolder)/*" instead of ls $dirtyfolder/* ? I've tried and both commands are equals. – Nicola Cossu May 02 '11 at 20:38
  • @nick-rulez: not really, because it was **not-tested**, I was more sure with that :). Nice to know, I'm going to simplify the answer then. – Emiliano Poggi May 02 '11 at 20:48
  • @empo: The grouping solution did not work for me. It gives out the error: The term 'get-destbytype' is not recognized as the name of a cmdlet, function, script file, or operable program – Animesh May 09 '11 at 19:53
  • @steeluser: `get-destbytype` is the function I've defined. Where did you place the function? Did you _dot-source_ it? – Emiliano Poggi May 09 '11 at 20:33
  • No I just put the function in my script itself. How I do dot source it? – Animesh May 09 '11 at 22:09
  • If you put your function in the script, make sure it's at the beginning of the script not at the end. However you may want know more about [SCRIPT SCOPE AND DOT SOURCING](http://technet.microsoft.com/en-us/library/dd819484.aspx). – Emiliano Poggi May 09 '11 at 22:24
  • @empo. Sorry for the late reply. The grouping solution is working fine. The only thing I have noticed is, both csv files and cs files go into a folder called `code spreadsheets`. Attached is the code I have modified for my user. Please help. Thanks a bunch again. http://paste.ubuntu.com/625701/ – Animesh Jun 13 '11 at 07:46
  • @steeluser: sorry, but it might be a good idea to create a new question summarizing your problem. The problem is probably in how extensions are matched; but you should give more details; a comment is too narrow for a satisfying question/answer. – Emiliano Poggi Jun 13 '11 at 08:08
1

This is my working test

$source = "e:\source" 
$dest = "e:\dest"
$file = gci $source | ? {-not $_.psiscontainer} 
$file | group -property extension | 
        % {if(!(test-path(join-path $dest -child $_.name.replace('.','')))) { new-item -type directory $(join-path $dest -child $_.name.replace('.','')).toupper() }}
$file | % {  move-item $_.fullname -destination $(join-path $dest -child $_.extension.replace(".",""))}

The script will find all different extensions within source folder. For each extension, if the folder doesn't already exist within destination, it will be created. Last row will loop each file from source and move it to the right subfolder destination.

If you want to put images with different extensions within the same folder you need to make some further check, using an if or a switch statement.

Nicola Cossu
  • 54,599
  • 15
  • 92
  • 98