如何在Visual Studio Code中,Unix-like系统下将所有文件的行尾(EOL)全部更改?

136

我使用Windows 10 Home,通常使用 Visual Studio Code (VS Code) 编辑 Linux Bash 脚本以及 PHP 和 JavaScript。

我不为 Windows 开发任何专用软件,无论编辑的文件扩展名是什么,我都希望默认的行尾符(EOL)都是类 Unix 的系统(Nix)。

如何确保在 Visual Studio Code 中,所有文件的 EOL 都是 Nix 呢?


我写了一些 Windows 下用 Visual Studio Code 编写的 Bash 脚本,并将其上传到 GitHub 作为一个项目的一部分。程序审查员检查后告诉我,这里存在有Windows EOLsBOM问题,如果将 EOLs 更改为 Nix,就可以解决该问题(至少我是这样理解的)。


因为我所有的开发都是面向 Linux 的,所以我希望默认情况下,任何我编辑的文件都具有 Nix EOLs,即使它是 Windows 特有的。

12个回答

161

被接受的答案解释了如何为所有文件执行此操作(使用设置中的files.eol),但是如果您需要覆盖该设置,则可以在右下角找到一个指示器,单击并更改该文件的设置。花了一段时间才注意到这是可点击的。

在消息栏的右下角查看CRLF


58
这只是针对当前文件的设置。问题是如何为所有文件设置。 - James
6
我点赞了被接受的答案,它确实回答了问题。这个答案的目的是指出,如果您对默认设置有异常,那么有一种简单的机制可以仅更改一个文件的文件结尾。这对于至少一些人(可能是 vscode 的新用户)来说肯定是有帮助的,并且他们会点赞。我想将其作为接受的答案的评论可能会更好? - Ian McGowan
Ian的图像可能会误导,你必须将其更改为lf换行符 - Timo
1
或者在“显示所有命令”列表(ctrl+shift+p)中执行“更改行尾序列”命令。 - dfours

133
我搜索了好几天,一直没有找到简单的解决方案,直到我找到了一些Git命令(来源),可以将所有文件从CRLF更改为LF
正如Mats所指出的(来源),在执行以下命令之前,请确保提交更改。
在根文件夹中键入以下内容。
git config core.autocrlf false

git rm --cached -r .         # Don’t forget the dot at the end

git reset --hard

34
在运行之前,请确保提交任何更改! :) - Mats
5
如果我早点看到这个评论就好了。 - Pascal Ganaye
你可以通过给个赞表达同样的意思 :D - haidar
对于任何人(可能包括我未来的自己)想要了解此答案中三个建议命令的源代码和/或理解它们的人,这里提供一些链接。 Git:处理行尾 - 解决方案git rm --cached -r . 的作用git rm --cached -r . 的文档另一个(相同的)SO答案 - Henke
关于这个问题的最佳答案 :) - Amir Mohammad Beheshti
显示剩余4条评论

86
在您的项目首选项中,添加/编辑以下配置选项:
"files.eol": "\n"

这是在提交639a3cb后添加的,所以您需要使用该提交后的版本。

注意:即使文件中只有一个 CRLF,上述设置也会被忽略,并且整个文件都将转换为 CRLF。您需要先将所有 CRLF 转换为 LF 才能在 Visual Studio Code 中打开它。

另请参见:https://github.com/Microsoft/vscode/issues/2957


7
此方法不会转换所有文件,而是单个文件。 - elliotching
我认为没有“vscode-all-files-eol-unix-like-solution”。 - Timo
对我来说,在与Linux环境共享的Git项目上,这并不起作用。我有时会使用以下命令:find . -not -path '*/.*' -type f \( -iname \*Dockerfile* -o -iname \*.sh \) -exec sed -i 's/\r//' {} \;,除此之外还要使用git config core.eol nativegit config core.autocrlf true。更多信息请参见https://dev59.com/C2kw5IYBdhLWcg3wUI_x#9977954。 - tuxErrante

28

您可以在Visual Studio Code设置中找到此选项。 它位于“文本编辑器”→“文件”→“Eol”下面。 在这里,您可以选择您想要的\n 或 \r\n 或自动。

输入图像描述


1
一种打开设置的方法是通过菜单 文件首选项设置。另一种方法是使用 Ctrl + , 快捷键。 - Peter Mortensen
“auto”选项可能真的很糟糕。 - Timo
不是解决方案,即使在设置中将其设置为 \n,所有文件的默认选项仍然是 CRLF。这是 2022 年的一个 bug。对 VSCode 感到羞耻。 - Mehmet Eyüpoğlu
我在设置中搜索了LF、CRLF、换行符、行尾符等内容,最终发现是"Eol"。 o.O - mgutt

28

转换现有文件的行尾

WSL

我们可以在 WSL 或您的 Shell 终端中使用 dos2unix 工具。

安装该工具:

sudo apt install dos2unix

转换当前目录中的行尾:

find -type f -print0 | xargs -0 dos2unix
如果有一些您希望从转换中排除的文件夹,请使用:

find -type f \
     -not -path "./<dir_to_exclude>/*" \
     -not -path "./<other_dir_to_exclude>/*" \
     -print0 | xargs -0 dos2unix

编辑于2023年

直接使用 PowerShell 7+(更快,支持多线程)

要在Windows上安装PowerShell 7,请按照此处的说明操作。

您需要已经安装了Chocolatey,并安装dos2unix for Chocolatey。

  1. 如果你还没有安装 Chocolatey,请按照这里的说明进行安装。

  2. 为 Chocolatey 安装 dos2unix

    1. 以管理员身份打开PowerShell终端

      pwsh.exe -new_console:a
      
    2. 安装dos2unix

    3. choco install dos2unix
      
    4. 关闭管理员终端

      exit
      

现在,我们可以从PowerShell使用dos2unix

# Set the parameters
$path = Get-Location
$numbOfThreads = 50
$exclude_patterns = "^.*(\.git|\.idea|node_modules|\.next|\.(jpeg|jpg|png|gif|mp4|mkv|mp3|wav)$).*$"

# Find files to convert
$files = Get-ChildItem -Path $path -Recurse -Include *.* -File -Force | Where-Object {$_.FullName -notmatch $exclude_patterns}
Write-Host "Found $($files.Count) files"

# Convert the files
$files | ForEach-Object -Parallel {
    dos2unix $_.FullName
} -ThrottleLimit $numbOfThreads


它如何处理带有BOM编码的UTF-8文件? - Peter Mortensen
如果你想要使用现代的方式来“查找”,可以在Debian上尝试使用“apt install fd-find”。 - Timo
1
谢谢!这是我在WSL上唯一有效的解决方案。 - Andrew Evt

10

两个已有的答案都是有用的,但不是我需要的。 我想要批量将工作区中的所有换行符从CRLF转换为LF。

我创建了一个简单的扩展来完成它

https://marketplace.visualstudio.com/items?itemName=vs-publisher-1448185.keyoti-changeallendoflinesequence

事实上,这是扩展的代码供参考

'use strict';

import * as vscode from 'vscode';
import { posix } from 'path';


export function activate(context: vscode.ExtensionContext) {

    // Runs 'Change All End Of Line Sequence' on all files of specified type.
    vscode.commands.registerCommand('keyoti/changealleol', async function () {

        async function convertLineEndingsInFilesInFolder(folder: vscode.Uri, fileTypeArray: Array<string>, newEnding: string): Promise<{ count: number }> {
            let count = 0;
            for (const [name, type] of await vscode.workspace.fs.readDirectory(folder)) {

                if (type === vscode.FileType.File && fileTypeArray.filter( (el)=>{return name.endsWith(el);} ).length>0){ 
                    const filePath = posix.join(folder.path, name);

                    var doc = await vscode.workspace.openTextDocument(filePath);

                    await vscode.window.showTextDocument(doc);
                    if(vscode.window.activeTextEditor!==null){
                        await vscode.window.activeTextEditor!.edit(builder => { 
                            if(newEnding==="LF"){
                                builder.setEndOfLine(vscode.EndOfLine.LF);
                            } else {
                                builder.setEndOfLine(vscode.EndOfLine.CRLF);
                            }
                            count ++; 
                        });

                    } else {
                        vscode.window.showInformationMessage(doc.uri.toString());
                    }
                }

                if (type === vscode.FileType.Directory && !name.startsWith(".")){
                    count += (await convertLineEndingsInFilesInFolder(vscode.Uri.file(posix.join(folder.path, name)), fileTypeArray, newEnding)).count;
                }
            }
            return { count };
        }

        let options: vscode.InputBoxOptions = {prompt: "File types to convert", placeHolder: ".cs, .txt", ignoreFocusOut: true};
        let fileTypes = await vscode.window.showInputBox(options);
        fileTypes = fileTypes!.replace(' ', '');
        let fileTypeArray: Array<string> = [];

        let newEnding = await vscode.window.showQuickPick(["LF", "CRLF"]);

        if(fileTypes!==null && newEnding!=null){
            fileTypeArray = fileTypes!.split(',');

            if(vscode.workspace.workspaceFolders!==null && vscode.workspace.workspaceFolders!.length>0){
                const folderUri = vscode.workspace.workspaceFolders![0].uri;
                const info = await convertLineEndingsInFilesInFolder(folderUri, fileTypeArray, newEnding);
                vscode.window.showInformationMessage(info.count+" files converted");

            }
        }

    });

}

我想要运行它在特定的文件夹中,为此我正在尝试编辑代码,但是我该如何运行它呢?你能给些建议吗? - Siddharth Choudhary
1
@SiddharthChoudhary 这段代码是一个VS Code扩展,所以要运行它,您必须将其作为扩展安装。好消息是,您可以从https://github.com/keyoti/VSCode-ChangeAllEOL获取该扩展 - 我相信您只需将其克隆到您的计算机上,在VS Code中打开它,然后按F5即可。它将打开一个VS Code的测试实例,您可以看到扩展程序的版本正在工作。更多信息请参见https://code.visualstudio.com/api/get-started/your-first-extension - Jim W says reinstate Monica

7

我在Windows电脑上遇到了同样的问题,每次打开文件时它都会将EOL设置为CRLF(尽管我明确设置了一个lf的配置,就像其他人建议的那样)。原来问题是我使用了错误的Git配置克隆了我的存储库。默认情况下是CRLF。无论如何,以下是我所做的,它完美地解决了这个问题。我的工作区中不再有CRLF

  1. 使用命令git config --global core.autocrlf false设置你的Git配置为lf
  2. 现在重新克隆你的项目:git clone ...
  3. 设置Visual Studio Code实例的菜单文件首选项设置文件Eol为“\n”。
  4. 打开项目,一切应该和预期一样。

7

其他人询问时,您可以在Visual Studio Code中使用"Files.eol"设置来更改每个文件的行尾。

"Files.eol": "\n"   // Unix
"Files.eol": "\r\n" // Windows

对我来说,VSCode需要小写的“files.eol”。尝试:CTRL+SHIFT+P -> 首选项:打开用户设置(JSON)-> 添加行“files.eol”:“\r\n”。 - SushiGuy

2
我知道这已经晚了,但最近我在寻找一种简单的方法,而不需要安装其他任何东西到我的系统中。
如果你已经安装了Windows版的Git,那么只需在所需的文件夹中打开一个Git Bash窗口,并运行dos2unix命令,它似乎默认已经捆绑在一起了。
find . -name "*.filetype" -exec dos2unix {} \;

它会自动将所有的换行符转换为LF。如果你懒得去使用“-name”来忽略二进制文件,它也会帮助你。
它对我很有帮助,希望对其他人也有帮助。

1

卸载 TypeScript

运行以下命令:

npm install -g typescript
git config --global core.autocrlf false

检查

git config --global core.autocrlf 

如果显示为false,请尝试克隆并重新运行该项目。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接