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
精彩评论