代码之家  ›  专栏  ›  技术社区  ›  Eddie Groves

Unix换行符到windows换行符(在windows上)

  •  26
  • Eddie Groves  · 技术社区  · 15 年前

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

    我非常乐意在PowerShell中找到一种至少可以检测到Unix文件的方法。

    对一个文件执行此操作很容易,但我想要的是更具可伸缩性的东西(因此倾向于使用PowerShell解决方案)。

    10 回复  |  直到 4 年前
        1
  •  43
  •   Peter Mortensen venu    3 年前

    如果您感兴趣,这里是纯PowerShell方式。

    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上的内容(如果存在,则删除内容),然后在将每个内容(在本例中为一行)写入文件时添加内容。这就是为什么您总是以文件结尾的行结束。

    另外,我编写了上面的代码,以便它只修改需要修改的文件。如果你不在乎,你可以移除 if 陈述哦,确保只有文件才能到达 ForEach-Object . 除此之外,您可以在管道开始时执行任何筛选操作。

        2
  •  14
  •   Miserable Variable    15 年前

    中有dos2unix和unix2dos Cygwin .

        3
  •  13
  •   Peter Mortensen venu    3 年前

    这似乎对我有用。

    Get-Content Unix.txt | Out-File Dos.txt
    
        4
  •  7
  •   Peter Mortensen venu    3 年前

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

    :se fileformat=dos|up
    

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

    :args C:\tmp\**\*.txt
    :argdo se fileformat=dos|up
    
        5
  •  2
  •   Peter Mortensen venu    3 年前

    Visual Studio . 菜单 文件 → 高级保存选项。。。 .

        6
  •  1
  •   Peter Mortensen venu    3 年前

    如果Cygwin不适合您,那么您可以使用许多独立的可执行文件 unix2dos 如果你在Windows下搜索,也可以自己写一个。请参阅我的类似(转换方向相反)问题 here .

        7
  •  1
  •   Peter Mortensen venu    3 年前

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

    底线是PowerShell代码对于大文件和大量文件来说效率非常低/速度很慢/不可用。它也不能保存 BOM

        8
  •  1
  •   Peter Mortensen venu    3 年前

    转换为Windows文本可能非常简单,如下所示:

    (Get-Content file) | Set-Content file
    

    使用以下命令(带负向后看)。没有 -nonewline

    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 所有物

        9
  •  0
  •   Dmitri    6 年前

    这对我很有用:

     Get-ChildItem -Recurse -File | % { $tmp = Get-Content $_; $tmp | Out-File "$_" -Encoding UTF8 }
    
        10
  •  0
  •   Peter Mortensen venu    3 年前

    在中打开以Unix行结尾的文件 WordPad 保存它会将所有行尾重写为DOS。对于大量文件来说,这有点费劲,但对于偶尔出现的几个文件来说,这已经足够好了。

        11
  •  0
  •   Peter Mortensen venu    3 年前

    建立在 js2010's answer 我创建了以下脚本:

    $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 }