Windows 中是否有一种方法(比如 PowerShell 或工具)可以递归目录并将任何 Unix 文件转换为 Windows 文件。
我会对 PowerShell 中至少检测 Unix 文件的方法感到非常满意。
对单个文件执行此操作很容易,但我追求的是更具可扩展性的东西(因此倾向于 PowerShellish 解决方案)。
Windows 中是否有一种方法(比如 PowerShell 或工具)可以递归目录并将任何 Unix 文件转换为 Windows 文件。
我会对 PowerShell 中至少检测 Unix 文件的方法感到非常满意。
对单个文件执行此操作很容易,但我追求的是更具可扩展性的东西(因此倾向于 PowerShellish 解决方案)。
如果您有兴趣,这里是纯 PowerShell 方式。
查找至少有一个 Unix 行结尾的文件 (PowerShell v1):
dir * -inc *.txt | %{ if (gc $_.FullName -delim "`0" | Select-String "[^`r]`n") {$_} }
这是您如何找到并将 Unix 行尾转换为 Windows 行尾的方法。需要注意的重要一点是,如果文件末尾还没有结束行,则会在文件末尾添加一个额外的行结束符 (\r\n)。如果你真的不想这样,我会发布一个如何避免它的例子(它有点复杂)。
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
}
}
上述工作是因为 PowerShell 将自动拆分 \n 上的内容(如果存在则删除 \r),然后在将每个内容(在本例中为一行)写入文件时添加 \r\n。这就是为什么你总是在文件末尾结束一行。
另外,我编写了上面的代码,以便它只修改它需要的文件。如果您不在乎,可以删除该if
声明。哦,确保只有文件到达ForEach-Object。除此之外,您可以在该管道开始时进行任何您想要的过滤。
Cygwin中有 dos2unix 和 unix2dos 。
这似乎对我有用。
Get-Content Unix.txt | Out-File Dos.txt
下载Vim,打开你的文件,然后发出
:se fileformat=dos|up
批处理多个文件(C:\tmp 中的所有 *.txt 文件 - 递归):
:args C:\tmp\**\*.txt
:argdo se fileformat=dos|up
您可以使用Visual Studio。菜单文件→高级保存选项...。
如果 Cygwin 不适合您,那么如果您在 google 周围搜索,有许多适用于 Windows 下的unix2dos的独立可执行文件,或者您可以自己编写一个。在此处查看我的类似(转换的相反方向)问题。
在包含 10,000 个文件的循环中测试先前答案中给出的代码的结果,其中许多文件的大小超过 50 KB:
底线是 PowerShell 代码对于大文件和大量文件非常低效/缓慢/无法使用。它也不保留BOM字节。我发现 unix2dos 7.2.3 是最快和最实用的解决方案。
转换为 Windows 文本可能很简单:
(Get-Content file) | Set-Content file
使用以下内容(带有消极的后视)。如果没有-nonewline
, set-content 会在底部添加一个额外的 `r`n。使用括号,您可以修改同一个文件。这对于意外对同一个文件执行两次应该是安全的。
function unix2dos ($infile, $outfile) {
(Get-Content -raw $infile) -replace "(?<!`r)`n","`r`n" |
Set-Content -nonewline $outfile
}
反过来是这样,Windows 到 Unix 文本:
function dos2unix ($infile, $outfile) {
(Get-Content -raw $infile) -replace "`r`n","`n" |
Set-Content -nonewline $outfile
}
这是另一个用于无法放入内存的大文件的版本。但是输出文件必须不同。
Function Dos2Unix ($infile, $outfile) {
Get-Content $infile -ReadCount 1000 | % { $_ -replace '$',"`n" } |
Set-Content -NoNewline $outfile
}
示例(输入和输出文件可以相同):
dos2unix dos.txt unix.txt
unix2dos unix.txt dos.txt
unix2dos file.txt file.txt
如果你有 Emacs,你可以用esc-x hexl-mode
. 记事本无法正确显示 Unix 文本;都将在同一条线上。我必须为 指定路径set-content
,因为-replace
会删除该pspath
属性。
在写字板中打开一个以 Unix 行结尾的文件并保存它会将所有行结尾重写为 DOS。对于大量文件来说有点费力,但对于偶尔的几个文件来说效果很好。
这个对我有用:
Get-ChildItem -Recurse -File | % { $tmp = Get-Content $_; $tmp | Out-File "$_" -Encoding UTF8 }
基于js2010 的回答,我创建了这个脚本:
$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 }