开发者

Know the from a fullname string if path is a folder or a file?

开发者 https://www.devze.com 2023-02-27 07:07 出处:网络
Sorry for the title. I\'ll try to explain better. Let\'s suppose that I run this command in order to get all paths of a directory and I want to redirect them to a text file.

Sorry for the title. I'll try to explain better.

Let's suppose that I run this command in order to get all paths of a directory and I want to redirect them to a text file.

gci e:\mytree -r | % {$_.fullname} | out-file e:\folderstructure.txt

Now I need to recreate this nested structure using new-item cmdlet.

Let's suppose now that I run this command:

gc e:\folderstructure.txt | % {
[system.io.fileinfo]$info = $开发者_Go百科_
write-host $info $info.extension
}

that produces this output:

E:\mytree\folder1 
E:\mytree\folder2 
E:\mytree\folder3 
E:\mytree\file1.txt .txt
E:\mytree\file12.txt .txt
E:\mytree\folder1\folder.with.dots .dots
E:\mytree\folder1\folder.with.dots\file inside folder with dots.txt .txt
E:\mytree\folder3\file4.doc .doc

As you can see folder.with.dots is a folder but "it's seen" as a file (it gives me .dots extension) because it contains dots within name. If I don't know all possible extensions of my files is there any property that can tell me if an object iscontainer or not so that I can use new-item with the right switch file or directory to create it?

I hope you have understood my problem despite my English. Thanks in advance.

edit. UPDATE after JPBlanc answer

Thank you very much. :)

I was trying in this way:

gc e:\folderstructure.txt | % {
[system.io.directoryinfo]$info = $_
if ($info.psiscontainer) {
write-host "$info is a folder" }
else {
write-host "$info is a file" }
}

and the output was:

E:\mytree\folder1 is a file
E:\mytree\folder2 is a file
E:\mytree\folder3 is a file
E:\mytree\file1.txt is a file
E:\mytree\file12.txt is a file
E:\mytree\folder1\folder.with.dots is a file
E:\mytree\folder1\folder.with.dots\file inside folder with dots.txt is a file
E:\mytree\folder3\file4.doc is a file

Following your advice:

gc e:\folderstructure.txt | % {
[system.io.directoryinfo]$info = $_
if ((get-item $info).psiscontainer) {
write-host "$info is a folder" }
else {
write-host "$info is a file" }
}

E:\mytree\folder1 is a folder
E:\mytree\folder2 is a folder
E:\mytree\folder3 is a folder
E:\mytree\file1.txt is a file
E:\mytree\file12.txt is a file
E:\mytree\folder1\folder.with.dots is a folder
E:\mytree\folder1\folder.with.dots\file inside folder with dots.txt is a file
E:\mytree\folder3\file4.doc is a file

everything works fine. Now I can achieve my goal. Thanks again.

LAST EDIT. I had another idea. I decided to check if an object is a file or a folder before creating txt file. After some difficulties (for example I've soon discovered that I can't redirect format-table that I was using to hide table headers to export-csv http://blogs.msdn.com/b/powershell/archive/2007/03/07/why-can-t-i-pipe-format-table-to-export-csv-and-get-something-useful.aspx ) I came up with this solution:

gci e:\mytree -r | 
select fullname,@{n='folder';e={ switch ($_.psiscontainer) { 
                                                                    true {1} 
                                                                    false {0}  
                                                                 }
                                     }
                     } | % {($_.fullname,$_.folder) -join ","} | out-file e:\structure.txt

that gets me this output:

E:\mytree\folder1,1
E:\mytree\folder2,1
E:\mytree\folder3,1
E:\mytree\file1.txt,0
E:\mytree\file12.txt,0
E:\mytree\folder1\folder.with.dots,1
E:\mytree\folder1\folder.with.dots\file inside folder with dots.txt,0
E:\mytree\folder3\file4.doc,0

So I can easily split two parameters and use new-item cmdlet accordingly to object type.


Both FileInfo type an DirectoryInfo type has got a property PSIsContainer, that allow you to see if the object is a directory or not.

PS C:\temp> (Get-Item 'Hello world.exe').PSIsContainer
False
PS C:\temp> (Get-Item 'c:\temp').PSIsContainer
True


I modified your code slightly to this:

gc c:\scripts\files.txt | % {
$item = Get-item $_
Write-Host $item.fullName $item.PSIscontainer
}

Now, my output looks like this:

C:\Scripts\mytree\folder1 True
C:\Scripts\mytree\folder2 True
C:\Scripts\mytree\file1.txt False
C:\Scripts\mytree\file2.txt False
C:\Scripts\mytree\folder.with.dots True
C:\Scripts\mytree\folder.with.dots\file inside folder with dots.txt False
0

精彩评论

暂无评论...
验证码 换一张
取 消