Is there a way (say PowerShell, or a tool) in Windows that can recurse over a directory and convert any Unix files to Windows files.
I\'d be perfectly happy with a wa
I spent 6 hours yesterday and today testing the code given above in a loop with 10,000 files, many of them >50kb in size. Bottom line, the powershell code is very inefficient/slow/unusable for large files and large number of files. It also does not preserve BOM bytes. I found unix2dos 7.2.3 to be the fastest and most practical solution. Hope this helps others and saves them time.
This seems to work for me.
Get-Content Unix.txt | Out-File Dos.txt
You can use Visual Studio. File -> Advanced Save Options...
Building on @js2010 answer I've created this script
$excludeFolders = "node_modules|dist|.vs";
$excludeFiles = ".*\.map.*|.*\.zip|.*\.png|.*\.ps1"
Function Dos2Unix {
[CmdletBinding()]
Param([Parameter(ValueFromPipeline)] $fileName)
Write-Host -Nonewline "."
$fileContents = Get-Content -raw $fileName
$containsCrLf = $fileContents | %{$_ -match "\r\n"}
If($containsCrLf -contains $true)
{
Write-Host "`r`nCleaing file: $fileName"
set-content -Nonewline -Encoding utf8 $fileName ($fileContents -replace "`r`n","`n")
}
}
Get-Childitem -File "." -Recurse |
Where-Object {$_.PSParentPath -notmatch $excludeFolders} |
Where-Object {$_.PSPath -notmatch $excludeFiles} |
foreach { $_.PSPath | Dos2Unix }
Here is the pure PowerShell way if you are interested.
Finding files with atleast one UNIX line ending (PowerShell v1):
dir * -inc *.txt | %{ if (gc $_.FullName -delim "`0" | Select-String "[^`r]`n") {$_} }
Here is how you find and covert UNIX line endings to Windows line endings. One important thing to note is that an extra line ending (\r\n) will be added to the end of the file if there isn't already a line ending at the end. If you really don't want that, I'll post an example of how you can avoid it (it is a bit more complex).
Get-ChildItem * -Include *.txt | ForEach-Object {
## If contains UNIX line endings, replace with Windows line endings
if (Get-Content $_.FullName -Delimiter "`0" | Select-String "[^`r]`n")
{
$content = Get-Content $_.FullName
$content | Set-Content $_.FullName
}
}
The above works because PowerShell will automatically split the contents on \n (dropping \r if they exist) and then add \r\n when it writes each thing (in this case a line) to the file. That is why you always end up with a line ending at the end of the file.
Also, I wrote the above code so that it only modifies files that it needs to. If you don't care about that you can remove the if statement. Oh, make sure that only files get to the ForEach-Object. Other than that you can do whatever filtering you want at the start of that pipeline.
It works for me:
Get-ChildItem -Recurse -File | % { $tmp = Get-Content $_; $tmp | Out-File "$_" -Encoding UTF8 }