Windows Vista Forums
Vista Forums Home Join Vista Forums Webcasts Vista Tutorials Tags

Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
Register at Vista forums...the world biggest Windows Vista resource Join Vista Forums Now

Go Back   Vista Forums > Microsoft Technical Newsgroups > PowerShell

Creating folder based on filename of a file

Update your Vista Drivers Update Your Drivers Now!!
Closed Thread
 
Thread Tools Display Modes
Old 12-17-2007   #1 (permalink)
Orrin
Guest


 

Creating folder based on filename of a file

Hello everyone.

I have a folder with some files in it like so:

AP1_0.dat
AP1_1.dat
AP2_0.dat
AP2_1.dat
AP2_2.dat
AP2_3.dat

How can I take the first 3 characters from the filenames and create
(in this case) two folders (AP1, AP2)?

I'd like to have a script that can read the files in a directory and
given that I tell it to use the first X number of characters from the
filenames to create directories for those files and then I can move
them based on the name of each file. I have the moving part down. I
even have a script that will work for one occasion, but since I know
Powershell can do get-itemproperty I figured there has to be a way to
get it to only use the first X (3, 4, however many) number of
characters and make folders based on that.

At this point I have two semi-functioning scripts:

A)
new-item AP1 -type directory
new-item AP2 -type directory
move-item "AP1*" AP1
move-item "AP2*" AP2

B)
get-itemproperty C:\new\*.* -name Name | new-item -type directory

Script A is basically doing things the old fashion way in my mind. B
is just what I was working on with gp. This will create folders
called "AP1_0.dat" and so on.. which is almost what I need. I just
need it to take the first three characters of the filename, not the
whole thing. Since it is creating new folders in the directory it is
ok if it reads AP1 again and makes the folders again since all AP1 &
AP2 folders will be empty at this point.

Thank you so much for any help you can give me with the get-
itemproperty or any other way of doing this.

Orrin

My System SpecsSystem Spec
Old 12-17-2007   #2 (permalink)
Marco Shaw [MVP]
Guest


 

Re: Creating folder based on filename of a file

Quote:

> Thank you so much for any help you can give me with the get-
> itemproperty or any other way of doing this.
>
> Orrin
Try this:
get-childitem . app*.txt | `
foreach-object{
$cur=$_.name
new-item -type directory $cur.substring(0,4) -whatif
move-item $_.name $cur.substring(0,4) -whatif
}

Remove the "-whatif" once you confirm you've got it.

You could also do:
$val=4
get-childitem . app*.txt | `
foreach-object{
$cur=$_.name
new-item -type directory $cur.substring(0,$val) -whatif
move-item $_.name $cur.substring(0,$val) -whatif
}


--
Microsoft MVP - Windows PowerShell
http://www.microsoft.com/mvp

PowerGadgets MVP
http://www.powergadgets.com/mvp

Blog:
http://marcoshaw.blogspot.com
My System SpecsSystem Spec
Old 12-17-2007   #3 (permalink)
Orrin
Guest


 

Re: Creating folder based on filename of a file

On Dec 17, 9:30 am, "Marco Shaw [MVP]" <marco.shaw@_NO_SPAM_gmail.com>
wrote:
Quote:

> Try this:
> get-childitem . app*.txt | `
> foreach-object{
> $cur=$_.name
> new-item -type directory $cur.substring(0,4) -whatif
> move-item $_.name $cur.substring(0,4) -whatif
>
> }
>
> Remove the "-whatif" once you confirm you've got it.
>
> You could also do:
> $val=4
> get-childitem . app*.txt | `
> foreach-object{
> $cur=$_.name
> new-item -type directory $cur.substring(0,$val) -whatif
> move-item $_.name $cur.substring(0,$val) -whatif
>
> }
>

I tried both of these and didn't get them to do anything (even after
removing -whatIf, but even with whatIf, it should tell me what it
would do and it isn't). I'm using Powershell 1.0 on Server 2003 if
that makes a difference.

Thank you so much for your help.
Orrin
My System SpecsSystem Spec
Old 12-17-2007   #4 (permalink)
Marco Shaw [MVP]
Guest


 

Re: Creating folder based on filename of a file

Quote:
Quote:

>> get-childitem . app*.txt
Quote:

> I tried both of these and didn't get them to do anything (even after
> removing -whatIf, but even with whatIf, it should tell me what it
> would do and it isn't). I'm using Powershell 1.0 on Server 2003 if
> that makes a difference.
>
> Thank you so much for your help.
> Orrin
I'm assuming you changed the path for get-childitem for your particular
case?

You had something like:

get-itemproperty C:\new\*.*

--
Microsoft MVP - Windows PowerShell
http://www.microsoft.com/mvp

PowerGadgets MVP
http://www.powergadgets.com/mvp

Blog:
http://marcoshaw.blogspot.com
My System SpecsSystem Spec
Old 12-17-2007   #5 (permalink)
Orrin
Guest


 

Re: Creating folder based on filename of a file

On Dec 17, 10:09 am, "Marco Shaw [MVP]"
<marco.shaw@_NO_SPAM_gmail.com> wrote:
Quote:
Quote:
Quote:

> >> get-childitem . app*.txt
> > I tried both of these and didn't get them to do anything (even after
> > removing -whatIf, but even with whatIf, it should tell me what it
> > would do and it isn't). I'm using Powershell 1.0 on Server 2003 if
> > that makes a difference.
>
Quote:

> > Thank you so much for your help.
> > Orrin
>
> I'm assuming you changed the path for get-childitem for your particular
> case?
>
> You had something like:
>
> get-itemproperty C:\new\*.*
>
> --
> Microsoft MVP - Windows PowerShellhttp://www.microsoft.com/mvp
>
> PowerGadgets MVPhttp://www.powergadgets.com/mvp
>
> Blog:http://marcoshaw.blogspot.com
Yeah, my file looks like this:

$val=4
get-childitem C:\new\app*.txt | `
foreach-object{
$cur=$_.name
new-item -type directory $cur.substring(0,$val) -whatif
move-item $_.name $cur.substring(0,$val) -whatif

}

Didn't give me the usual -whatIf response. It just gave me another PS
prompt. I also tried it like this:

$val=4
get-childitem C:\new\AP*.txt | `
foreach-object{
$cur=$_.name
new-item -type directory $cur.substring(0,$val) -whatif
move-item $_.name $cur.substring(0,$val) -whatif

}

Because my filenames start out AP1 and AP2. Still nothing. I'm still
pretty new to Powershell but I do kind of understand what is going on
here. I really appreciate any help I can get.

Thank you.

Orrin
My System SpecsSystem Spec
Old 12-17-2007   #6 (permalink)
Shay Levi
Guest


 

Re: Creating folder based on filename of a file

Try this:



$path= "c:\scripts\temp"

## get all dat files
$dats = Get-ChildItem $path -filter ap*.dat

## get unique values for all dat file names, returns only AP1,AP2
$prefix = $dats | foreach {$_.name.substring(0,3)} | Get-Unique -AsString

## foreach create new directory
$prefix | foreach { new-item -path $path -type directory -name $_ -force}

## move files to its corresponding directory
$dats | foreach { move-item -Path $_.fullname -Destination "$path\$($_.name.substring(0,3))"}





-----
Shay Levi
$cript Fanatic
http://scriptolog.blogspot.com
Hebrew weblog: http://blogs.microsoft.co.il/blogs/scriptfanatic


Quote:

> Hello everyone.
>
> I have a folder with some files in it like so:
>
> AP1_0.dat
> AP1_1.dat
> AP2_0.dat
> AP2_1.dat
> AP2_2.dat
> AP2_3.dat
> How can I take the first 3 characters from the filenames and create
> (in this case) two folders (AP1, AP2)?
>
> I'd like to have a script that can read the files in a directory and
> given that I tell it to use the first X number of characters from the
> filenames to create directories for those files and then I can move
> them based on the name of each file. I have the moving part down. I
> even have a script that will work for one occasion, but since I know
> Powershell can do get-itemproperty I figured there has to be a way to
> get it to only use the first X (3, 4, however many) number of
> characters and make folders based on that.
>
> At this point I have two semi-functioning scripts:
>
> A)
> new-item AP1 -type directory
> new-item AP2 -type directory
> move-item "AP1*" AP1
> move-item "AP2*" AP2
> B)
> get-itemproperty C:\new\*.* -name Name | new-item -type directory
> Script A is basically doing things the old fashion way in my mind. B
> is just what I was working on with gp. This will create folders
> called "AP1_0.dat" and so on.. which is almost what I need. I just
> need it to take the first three characters of the filename, not the
> whole thing. Since it is creating new folders in the directory it is
> ok if it reads AP1 again and makes the folders again since all AP1 &
> AP2 folders will be empty at this point.
>
> Thank you so much for any help you can give me with the get-
> itemproperty or any other way of doing this.
>
> Orrin
>

My System SpecsSystem Spec
Old 12-17-2007   #7 (permalink)
Mike Miller
Guest


 

Re: Creating folder based on filename of a file

Everybody stand back.... http://xkcd.com/208/

$dir = "c:\testfolder"
get-childitem -path $dir |
where-object -filterscript {$_.name -match "^(\w\w\w).*\.dat$"} |
foreach-object -process {
new-item -force ($dir + "\" + $matches[1]) -type directory;
move-item -path $_.FullName -destination ($dir + "\" + $matches[1]);
}

The script is a little noisy with the new-item line... I'm too new to
PowerShell to know the best way to silence this. Maybe somebody else knows?
I suppose you could wrap a check condition to see if the directory already
exists.

I realized just now your question was actually how to get just the first 3
characters of the filename. For that, you could use substring. eg.
$_.name.substring(0,3)

I prefer regex, mainly because you can use it to filter out things that
perhaps should be processed. For example, maybe somebody creates a log file
in your data directory called logfile.log. It'd end up getting moved to a
LOG subdirectory. That person might be wondering where there file went, and
you might be wondering why you suddenly have this log file trying to be
processed.

Mike


"Orrin" <oedenfield@xxxxxx> wrote in message
news:0369f3a5-06d9-48c8-94e2-13a87ad3765e@xxxxxx
Quote:

> Hello everyone.
>
> I have a folder with some files in it like so:
>
> AP1_0.dat
> AP1_1.dat
> AP2_0.dat
> AP2_1.dat
> AP2_2.dat
> AP2_3.dat
>
> How can I take the first 3 characters from the filenames and create
> (in this case) two folders (AP1, AP2)?
>
> I'd like to have a script that can read the files in a directory and
> given that I tell it to use the first X number of characters from the
> filenames to create directories for those files and then I can move
> them based on the name of each file. I have the moving part down. I
> even have a script that will work for one occasion, but since I know
> Powershell can do get-itemproperty I figured there has to be a way to
> get it to only use the first X (3, 4, however many) number of
> characters and make folders based on that.
>
> At this point I have two semi-functioning scripts:
>
> A)
> new-item AP1 -type directory
> new-item AP2 -type directory
> move-item "AP1*" AP1
> move-item "AP2*" AP2
>
> B)
> get-itemproperty C:\new\*.* -name Name | new-item -type directory
>
> Script A is basically doing things the old fashion way in my mind. B
> is just what I was working on with gp. This will create folders
> called "AP1_0.dat" and so on.. which is almost what I need. I just
> need it to take the first three characters of the filename, not the
> whole thing. Since it is creating new folders in the directory it is
> ok if it reads AP1 again and makes the folders again since all AP1 &
> AP2 folders will be empty at this point.
>
> Thank you so much for any help you can give me with the get-
> itemproperty or any other way of doing this.
>
> Orrin

My System SpecsSystem Spec
Old 12-17-2007   #8 (permalink)
Kirk Munro
Guest


 

Re: Creating folder based on filename of a file

The problem you're facing is Get-ChildItem is used to enumerate the contents
of a directory. So when you do this:

get-childitem C:\new\AP*.dat | `

you're telling PowerShell to look for any directory that matches
C:\new\AP*.txt and return the files within that directory. Obviously that
isn't what you want to do here. You need to change this to do one of two
things:

get-childitem C:\new -filter AP*.dat | ` # as Shay already pointed out

or

get-item C:\new\AP*.dat | ` # an alternative method

Also, if some of the files could be hidden, you need to use the -force
parameter for get-childitem or get-item to enumerate them as well. And if
you're moving hidden or read-only files, you need -force for the move-item
cmdlet as well.

--
Kirk Munro
Poshoholic
http://poshoholic.com


"Orrin" <oedenfield@xxxxxx> wrote in message
news:a459debd-ca23-4a7f-981b-ee54df8dbce2@xxxxxx
Quote:

> On Dec 17, 10:09 am, "Marco Shaw [MVP]"
> <marco.shaw@_NO_SPAM_gmail.com> wrote:
Quote:
Quote:

>> >> get-childitem . app*.txt
>> > I tried both of these and didn't get them to do anything (even after
>> > removing -whatIf, but even with whatIf, it should tell me what it
>> > would do and it isn't). I'm using Powershell 1.0 on Server 2003 if
>> > that makes a difference.
>>
Quote:

>> > Thank you so much for your help.
>> > Orrin
>>
>> I'm assuming you changed the path for get-childitem for your particular
>> case?
>>
>> You had something like:
>>
>> get-itemproperty C:\new\*.*
>>
>> --
>> Microsoft MVP - Windows PowerShellhttp://www.microsoft.com/mvp
>>
>> PowerGadgets MVPhttp://www.powergadgets.com/mvp
>>
>> Blog:http://marcoshaw.blogspot.com
>
> Yeah, my file looks like this:
>
> $val=4
> get-childitem C:\new\app*.txt | `
> foreach-object{
> $cur=$_.name
> new-item -type directory $cur.substring(0,$val) -whatif
> move-item $_.name $cur.substring(0,$val) -whatif
>
> }
>
> Didn't give me the usual -whatIf response. It just gave me another PS
> prompt. I also tried it like this:
>
> $val=4
> get-childitem C:\new\AP*.txt | `
> foreach-object{
> $cur=$_.name
> new-item -type directory $cur.substring(0,$val) -whatif
> move-item $_.name $cur.substring(0,$val) -whatif
>
> }
>
> Because my filenames start out AP1 and AP2. Still nothing. I'm still
> pretty new to Powershell but I do kind of understand what is going on
> here. I really appreciate any help I can get.
>
> Thank you.
>
> Orrin

My System SpecsSystem Spec
Old 12-17-2007   #9 (permalink)
Kirk Munro
Guest


 

Re: Creating folder based on filename of a file

Mike,

You could use Test-Path to see if the directory exists before trying to
create it, and/or pipe the output to null to suppress the output from
new-item.

e.g.
if (-not (test-path "$dir\$($matches[1])")) {
new-item "$dir\$($matches[1])" -type directory | out-null
}

or

new-item -force "$dir\$($matches[1])" -type directory | out-null

--
Kirk Munro
Poshoholic
http://poshoholic.com


"Mike Miller" <mike@xxxxxx> wrote in message
news:uEKPXhMQIHA.1164@xxxxxx
Quote:

> Everybody stand back.... http://xkcd.com/208/
>
> $dir = "c:\testfolder"
> get-childitem -path $dir |
> where-object -filterscript {$_.name -match "^(\w\w\w).*\.dat$"} |
> foreach-object -process {
> new-item -force ($dir + "\" + $matches[1]) -type directory;
> move-item -path $_.FullName -destination ($dir + "\" + $matches[1]);
> }
>
> The script is a little noisy with the new-item line... I'm too new to
> PowerShell to know the best way to silence this. Maybe somebody else
> knows? I suppose you could wrap a check condition to see if the directory
> already exists.
>
> I realized just now your question was actually how to get just the first 3
> characters of the filename. For that, you could use substring. eg.
> $_.name.substring(0,3)
>
> I prefer regex, mainly because you can use it to filter out things that
> perhaps should be processed. For example, maybe somebody creates a log
> file in your data directory called logfile.log. It'd end up getting moved
> to a LOG subdirectory. That person might be wondering where there file
> went, and you might be wondering why you suddenly have this log file
> trying to be processed.
>
> Mike
>
>
> "Orrin" <oedenfield@xxxxxx> wrote in message
> news:0369f3a5-06d9-48c8-94e2-13a87ad3765e@xxxxxx
Quote:

>> Hello everyone.
>>
>> I have a folder with some files in it like so:
>>
>> AP1_0.dat
>> AP1_1.dat
>> AP2_0.dat
>> AP2_1.dat
>> AP2_2.dat
>> AP2_3.dat
>>
>> How can I take the first 3 characters from the filenames and create
>> (in this case) two folders (AP1, AP2)?
>>
>> I'd like to have a script that can read the files in a directory and
>> given that I tell it to use the first X number of characters from the
>> filenames to create directories for those files and then I can move
>> them based on the name of each file. I have the moving part down. I
>> even have a script that will work for one occasion, but since I know
>> Powershell can do get-itemproperty I figured there has to be a way to
>> get it to only use the first X (3, 4, however many) number of
>> characters and make folders based on that.
>>
>> At this point I have two semi-functioning scripts:
>>
>> A)
>> new-item AP1 -type directory
>> new-item AP2 -type directory
>> move-item "AP1*" AP1
>> move-item "AP2*" AP2
>>
>> B)
>> get-itemproperty C:\new\*.* -name Name | new-item -type directory
>>
>> Script A is basically doing things the old fashion way in my mind. B
>> is just what I was working on with gp. This will create folders
>> called "AP1_0.dat" and so on.. which is almost what I need. I just
>> need it to take the first three characters of the filename, not the
>> whole thing. Since it is creating new folders in the directory it is
>> ok if it reads AP1 again and makes the folders again since all AP1 &
>> AP2 folders will be empty at this point.
>>
>> Thank you so much for any help you can give me with the get-
>> itemproperty or any other way of doing this.
>>
>> Orrin
>
>

My System SpecsSystem Spec
Old 12-17-2007   #10 (permalink)
Keith Hill [MVP]
Guest


 

Re: Creating folder based on filename of a file

"Kirk Munro" <sorry@xxxxxx> wrote in message
news:OgyCi#MQIHA.5016@xxxxxx
Quote:

> The problem you're facing is Get-ChildItem is used to enumerate the
> contents of a directory. So when you do this:
>
> get-childitem C:\new\AP*.dat | `
>
> you're telling PowerShell to look for any directory that matches
> C:\new\AP*.txt and return the files within that directory.
Not quite. GCI looks for any items not just directories and based on just
trying this it returns the directory *if* there is any wildcarding involved
e.g.:

40> gci c:\temp\ap*.dat


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp


Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 12/17/2007 10:31 AM <DIR> AP1.dat

However if there isn't a wildcard involved then it behaves like you say:

41> gci C:\temp\AP1.dat


Directory: Microsoft.PowerShell.Core\FileSystem::C:\temp\AP1.dat


Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 12/17/2007 10:31 AM 0 foo.dat

For what its worth, here is another way to do this:

115> gci c:\temp\ap*.dat | ?{!$_.PSIsContainer} | group {(Join-Path
$_.PSParentPath $_.Name.Substring(0,3))} | %{ni -typ
e directory $_.Name -ea 0 -wh; $dir = $_.Name; $_.group | %{mi $_ $dir -wh}}
What if: Performing operation "Create Directory" on Target "Destination:
C:\temp\AP1".
What if: Performing operation "Move File" on Target "Item: C:\temp\AP1_0.dat
Destination: C:\temp\AP1".
What if: Performing operation "Move File" on Target "Item: C:\temp\AP1_1.dat
Destination: C:\temp\AP1".
What if: Performing operation "Create Directory" on Target "Destination:
C:\temp\AP2".
What if: Performing operation "Move File" on Target "Item: C:\temp\AP2_0.dat
Destination: C:\temp\AP2".
What if: Performing operation "Move File" on Target "Item: C:\temp\AP2_1.dat
Destination: C:\temp\AP2".
What if: Performing operation "Move File" on Target "Item: C:\temp\AP2_2.dat
Destination: C:\temp\AP2".
What if: Performing operation "Move File" on Target "Item: C:\temp\AP2_3.dat
Destination: C:\temp\AP2".

--
Keith

My System SpecsSystem Spec
Closed Thread

Thread Tools
Display Modes



Similar Threads
Thread Thread Starter Forum Replies Last Post
File save requester filename annoyance Jimbo Vista file management 0 05-22-2008 10:29 AM
Arrays, creating based on strings Jacob Saaby Nielsen PowerShell 13 11-30-2007 01:52 AM
How to set select objects in folder view to width of filename? Baltimoron Vista file management 1 09-20-2007 07:59 PM