Try this one.
foreach($i in Get-ChildItem -Recurse) {
if ($i.PSIsContainer) {
continue
}
$dest = $i.Fullname.Replace($PWD, "some_folder")
if (!(Test-Path $(Split-Path $dest -Parent))) {
New-Item $(Split-Path $dest -Parent) -type Directory
}
get-content $i | out-file -encoding utf8 -filepath $dest
}
It grabs the full path of the file and replaces the current directory with the one you want. For example, you run this command in the directory C:\1\
($PWD = C:\1\
). If it finds the file C:\1\2\file.txt
, it'll give you a $dest
of some_folder\2\file.txt
.
The first if block is there so you don't try to convert a directory.
The directories have to be created if they don't already exist - I originally forgot that.
If you want UTF8 without BOM, replace the get-content $i | out-file -encoding utf8 -filepath $dest
line with the following (source):
$filecontents = Get-Content $i
$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding($False)
[System.IO.File]::WriteAllLines($i, $filecontents, $Utf8NoBomEncoding)
Note that this may not be very performant for larger files, since it reads entire files into memory before writing them again. If efficiency is needed, it is possible to read line by line, or even a specific number of bytes at a time. However, I'd rather just write a quick program in C# by that point (since you'd be using .NET fuctions in PS anyway).
1Which version of PowerShell is this? In the one that came with (my copy of) Win7 (v2?), there's
Get-ChildItem
but notGet-Children
... – Bob – 2012-03-07T13:12:55.777It was a misspelling, I've corrected it. – Roman – 2012-03-07T13:35:36.697