35

Windows 中是否有一种方法(比如 PowerShell 或工具)可以递归目录并将任何 Unix 文件转换为 Windows 文件。

我会对 PowerShell 中至少检测 Unix 文件的方法感到非常满意。

对单个文件执行此操作很容易,但我追求的是更具可扩展性的东西(因此倾向于 PowerShellish 解决方案)。

4

11 回答 11

44

如果您有兴趣,这里是纯 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。除此之外,您可以在该管道开始时进行任何您想要的过滤。

于 2009-04-07T20:02:40.837 回答
14

Cygwin中有 dos2unix 和 unix2dos 。

于 2009-04-07T04:05:04.713 回答
13

这似乎对我有用。

Get-Content Unix.txt | Out-File Dos.txt
于 2016-09-19T14:26:35.693 回答
7

下载Vim,打开你的文件,然后发出

:se fileformat=dos|up

批处理多个文件(C:\tmp 中的所有 *.txt 文件 - 递归):

:args C:\tmp\**\*.txt
:argdo se fileformat=dos|up
于 2009-04-07T04:31:25.833 回答
2

您可以使用Visual Studio。菜单文件高级保存选项...。

于 2009-04-07T04:35:11.630 回答
1

如果 Cygwin 不适合您,那么如果您在 google 周围搜索,有许多适用于 Windows 下的unix2dos的独立可执行文件,或者您可以自己编写一个。在此处查看我的类似(转换的相反方向)问题。

于 2009-04-07T04:13:04.037 回答
1

在包含 10,000 个文件的循环中测试先前答案中给出的代码的结果,其中许多文件的大小超过 50 KB:

底线是 PowerShell 代码对于大文件和大量文件非常低效/缓慢/无法使用。它也不保留BOM字节。我发现 unix2dos 7.2.3 是最快和最实用的解决方案。

于 2015-08-01T01:21:59.047 回答
1

转换为 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属性。

于 2018-10-01T14:21:57.107 回答
0

在写字板中打开一个以 Unix 行结尾的文件并保存它会将所有行结尾重写为 DOS。对于大量文件来说有点费力,但对于偶尔的几个文件来说效果很好。

于 2014-12-05T23:14:17.620 回答
0

这个对我有用:

 Get-ChildItem -Recurse -File | % { $tmp = Get-Content $_; $tmp | Out-File "$_" -Encoding UTF8 }
于 2018-11-13T01:44:27.040 回答
0

基于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 }
于 2020-04-22T10:44:31.350 回答