Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

remove last element from an array

2,560 views
Skip to first unread message

sardinian_guy

unread,
Jul 25, 2009, 11:01:16 AM7/25/09
to

Hi guys. I have a text file that contains several paths.
From each one I need to remove file name.

I wrote this code

$str = "C:\Documents and Settings\Username\desktop\folder\file.txt"
$array = $str.split("\")
$path = [string]::Join("\",$array[0..($array.length-2)])
$path

but I'd like to know if there is a better way to accomplish this task.
Thanks in advance. :)


--
sardinian_guy

Hans Dingemans

unread,
Jul 25, 2009, 11:54:57 AM7/25/09
to
I would use .NET classes for that :-)

PS> $str = "C:\Documents and Settings\Username\desktop\folder\file.txt"
PS> [system.io.path]::GetDirectoryName($str)


C:\Documents and Settings\Username\desktop\folder

PS>

http://msdn.microsoft.com/en-us/library/system.io.path.getdirectoryname.aspx

GetDirectoryName is a so called static method of the Path class in the
system.io namespace. Static methods are called using the [classname]::
(double colon).
E.g.:

PS> [math]::sqrt(24)
4.89897948556636
PS>

Also try...

PS> [system.io.path] | Get-Member -Static

... what other nice methods can help you out, e.g. filename w/wo extension,
etc.

HTH,
Hans


"sardinian_guy" <gu...@unknown-email.com> wrote in message
news:339b36694014a666...@nntp-gateway.com...

sardinian_guy

unread,
Jul 25, 2009, 3:26:45 PM7/25/09
to

Hans Dingemans;1098719 Wrote:
> I would use .NET classes for that :-)
>
> PS> $str = "C:\Documents and Settings\Username\desktop\folder\file.txt"
> PS> [system.io.path]::GetDirectoryName($str)
> C:\Documents and Settings\Username\desktop\folder
> PS>
>
> 'Path.GetDirectoryName Method (System.IO)'
> (http://msdn.microsoft.com/en-us/library/system.io.path.getdirectoryname.aspx)

>
> GetDirectoryName is a so called static method of the Path class in the
> system.io namespace. Static methods are called using the [classname]::
> (double colon).
> E.g.:
>
> PS> [math]::sqrt(24)
> 4.89897948556636
> PS>
>
> Also try...
>
> PS> [system.io.path] | Get-Member -Static
>
> .... what other nice methods can help you out, e.g. filename w/wo
> extension,
> etc.
>
> HTH,
> Hans
>
>
> "sardinian_guy" <gu...@xxxxxx-email.com> wrote in message
> news:339b36694014a666...@xxxxxx-gateway.com...> > >
> > >
> > > Hi guys. I have a text file that contains several paths.
> > > From each one I need to remove file name.
> > >
> > > I wrote this code
> > >
> > > $str = "C:\Documents and Settings\Username\desktop\folder\file.txt"
> > > $array = $str.split("\")
> > > $path = [string]::Join("\",$array[0..($array.length-2)])
> > > $path
> > >
> > > but I'd like to know if there is a better way to accomplish this
> > task.
> > > Thanks in advance. :)
> > >
> > >
> > > --
> > > sardinian_guy > >

I knew

gci | select directoryname

but I didn't know that it was possible to retrieve directory name from
a string.

Moreover your suggestion

[system.io.path] | Get-Member -Static

has opened me a new world. Now I can finish my script. I needed to move
a lot of files according to the content of the txt file. Thank you very
much Hans. Have a nice weekend. Regards, Nicola. :)


--
sardinian_guy

Bob Landau

unread,
Jul 25, 2009, 4:33:01 PM7/25/09
to

Its good to have several ways. Before going to far though check the
documentation for Split-Path

sardinian_guy

unread,
Jul 26, 2009, 3:17:39 AM7/26/09
to

Thanks Bob for you reply. :)

I have another questions

I made some changes to my script. Now my txt file contains the paths
but I removed file extensions. Example of contents:

C:\Documents and Settings\Username\desktop\folder\file

C:\Documents and Settings\Username\desktop\folder\file2
C:\Documents and Settings\Username\desktop\folder\file3

and so on.

My folder contains file.doc,file.pdf,file2.doc,file2.pdf and so on and
I have to move those files according to the path.


This script doesn't work

set-location "C:\my_path\my_folder"
$txt = gc elenco.txt
foreach($linea in $txt) {
$file = ([system.IO.Path]::getfilename($linea)).trim()
$folder = ([system.IO.Path]::getdirectoryname($linea)).trim()
move-Item $file* -destination $folder -whatif
##write-Host $file,$folder
}

but it doesn't return any error.

However if I write

move-Item "file*" -destination "C:\my_path\my_folder" -whatif

everything works well.

Instead if I change my script in this way

set-location "C:\my_path\my_folder"
$txt = gc elenco.txt
foreach($linea in $txt) {
$file = ([system.IO.Path]::getfilename($linea)).trim()
$folder = ([system.IO.Path]::getdirectoryname($linea)).trim()
Get-ChildItem $file* | move-Item -destination $folder -whatif
##write-Host $file,$folder
}


everything is ok.
Why I can't use variable and asterisk to move files but I have to use
gci to retrieve my files within the loop?


--
sardinian_guy

Bob Landau

unread,
Jul 26, 2009, 12:24:00 PM7/26/09
to
Sardinian_guy

One thing I'd like to recomend to you and anyone else willing to listen is

Always, Always prefer the cmdlets or PS method over .NET.

There are many reasons for this

1) they are easier for scripters of and non-scripters to use
2) help is integrated within the environment
3) they work well within the Powershell environment i.e. Pipeline, Current
Directory
4) less code to write; less bugs
and so on.


Regarding your script I'm assuming you are wanting to use wildcards

1) the [io.path] class does not work with the filesystem so expanding
wildcards doesn't work. You will need to use the [io.directory] class if you
choose to go this route

Note if you do choose [io.directory] there will be a discrepency between the
currently location set by Powershell and that which the .NET classes use.

2) Powershell treats wildcard matches resolve to the empty string (no match)
as a success. It will not WARN you as in this line below

>>>> move-Item $file* -destination $folder -whatif

same holds true with Remove and Copy

In general this is the proper behavior however at least in my opinion the
cmdlets SHOULD warn if a wildcard expands to a non-existent file.

While I have very few complaints this is number two or three on my list.
When I bugged this the statement I got back was this is expected behavior.

What this means is $file doesn't represent anything in that directory

I've no idea why the second works and not the first; $var* will work
correctly in general. However why not just be straight forward with what you
want to do. The below pattern should also work within your loop. Resolve-Item
handles all the hard stuff

Figures out the FullPath regardless of what it is
Expands out wildcards and returns a list


Resolve-Item *.txt | Move-Item -Destination $folder

0 new messages