转换整个目录树的行结尾 (Git)
以下情况:
我正在运行 OS X 的 Mac 上工作,最近加入了一个项目,该项目迄今为止的成员都使用 Windows。我的首要任务之一是在 Git 存储库中设置代码库,因此我从 FTP 中提取目录树,并尝试将其签入我在本地准备的 Git 存储库中。当尝试这样做时,我得到的只是这个
fatal: CRLF would be replaced by LF in blog/license.txt.
,因为这会影响“blog”文件夹下的所有文件,所以我正在寻找一种方法来方便地将树中的所有文件转换为 Unix 行结尾。有没有一个工具可以开箱即用,或者我自己编写一些脚本?
作为参考,我有关行结束的 Git 配置:
core.safecrlf=true
core.autocrlf=input
Following situation:
I'm working on a Mac running OS X and recently joined a project whose members so far all use Windows. One of my first tasks was to set up the codebase in a Git repository, so I pulled the directory tree from FTP and tried to check it into the Git repo I had prepared locally. When trying to do this, all I got was this
fatal: CRLF would be replaced by LF in blog/license.txt.
Since this affects all files below the "blog" folder, I'm looking for a way to conveniently convert ALL files in the tree to Unix line-endings. Is there a tool that does that out of the box or do I get scripting something myself?
For reference, my Git config concerning line-endings:
core.safecrlf=true
core.autocrlf=input
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
dos2unix 会为你做到这一点。相当简单的过程。
感谢 toolbear,这里有一个单行代码,可以递归地替换行结尾并正确处理空格、引号和 shell 元字符。
如果您使用 dos2unix 6.0,二进制文件将被忽略。
dos2unix does that for you. Fairly straight forward process.
Thanks to toolbear, here is a one-liner that recursively replaces line endings and properly handles whitespace, quotes, and shell meta chars.
If you're using dos2unix 6.0 binary files will be ignored.
假设您有 GNU grep 和 perl 这将在当前目录下的非二进制文件中递归地将 CRLF 转换为 LF:
它是如何工作的
在当前目录下递归查找;将
.
更改为blog
或whatev
子目录以限制替换:仅匹配常规文件:
测试文件是否包含 CRLF。排除二进制文件。为每个常规文件运行
grep
命令。这就是排除二进制文件的代价。如果您有旧的grep
,您可以尝试使用file
命令构建测试:将 CRLF 替换为 LF。带有第二个
-exec
的'+'
告诉find
累积匹配的文件并将它们传递给一次(或尽可能少的)调用该命令——类似于通过管道传输到 xargs,但如果文件路径包含空格、引号或其他 shell 元字符,则不会出现问题。-pi
中的i
告诉 perl 就地修改文件。您可以在此处使用sed
或awk
进行一些工作,并且您可能会将 '+' 更改为 ';'并为每场比赛调用一个单独的过程:Assuming you have GNU
grep
andperl
this will recursively convert CRLF to LF in non-binary files under the current directory:How it Works
Find recursively under current directory; change
.
toblog
orwhatev
subdirectories to limit the replacement:Only match regular files:
Test if file contains CRLF. Exclude binary files. Runs
grep
command for every regular file. That's the price of excluding binaries. If you have an oldgrep
you could try building a test using thefile
command:Replace CRLF with LF. The
'+'
with the second-exec
tellsfind
to accumulate matching files and pass them to one (or as few as possible) invocations of the command -- like piping toxargs
, but without problems if file path contains spaces, quotes, or other shell meta characters. Thei
in-pi
tells perl to modify the file in place. You could usesed
orawk
here with some work, and you'll probably change '+' to ';' and invoke a separate process for each match:这是一个更好的选择:瑞士锉刀。它在子目录中递归地工作,并正确处理空格和特殊字符。
您所要做的就是:
额外奖励:sfk 还可以进行许多其他转换。请参阅下面的完整列表:
编辑:警告:在包含二进制文件的文件夹上运行此命令时要小心,因为它会有效地破坏您的文件,特别是 .git 目录。如果是这种情况,请不要在整个文件夹中运行 sfk,而是选择特定的文件扩展名(*.rb、*.py 等)。示例:sfk remcr -dir Chef -file .rb -file .json -file .erb -file .md
Here's a better option: Swiss File Knife. It works recursively across sub-directories, and handles properly spaces and special characters.
All you have to do is:
Bonus: sfk also does lots of other conversions. See below for the full list:
EDIT: a word of caution: be careful when running this on folders that have binary files, as it will effectively destroy your files, particularly .git directories. If this is your case, do not run sfk in the entire folder, but select specific file extensions instead (*.rb, *.py, etc). Example:
sfk remcr -dir chef -file .rb -file .json -file .erb -file .md
这更安全,因为它可以避免损坏您的 git 存储库。将 .git、.svn 添加或替换为 .bzr、.hg 或您使用的任何源代码控制到不列表。
This is much safer as it avoids corrupting your git repo. Add or replace .git, .svn with .bzr, .hg or whatever source control your using to the not list.
在 OS X 上,这对我有用:
警告:请在执行此命令之前备份您的目录。
On OS X, this worked for me:
Warning: Please backup your directory before executing this command.
当前接受的答案使用
find -exec
和dos2unix
但现在这是不必要的,因为绝大多数 shell,包括 Bash,都支持使用通配符对所有文件进行操作在目录中(称为路径名扩展或通配)。不使用 dos2unix 的答案甚至更糟糕,因为它们进行幼稚的搜索和替换,这将不可逆转地损坏二进制文件,例如可执行文件、图像和视频,甚至
的内容。 git
目录。dos2unix
和unix2dos
都是无处不在的轻量级工具,它们已预安装在我使用过的每个基于 UNIX 的系统上,这意味着它们几乎肯定已经安装在你的系统。默认情况下,它们还会跳过非文本文件,从而使它们可以安全地以这种方式在整个目录上使用,这与其他答案不同。将所有行结尾转换为 UNIX 行结尾 (LF)
将所有行结尾转换为 Windows 行结尾 (CRLF)
不需要
-v
/--verbose
开关但会将正在转换的文件输出到控制台。The current accepted answer uses
find -exec
withdos2unix
but this is unnecessary nowadays because the vast majority of shells, including Bash, support the use of a wildcard to operate on all files in a directory (known as pathname expansion or globbing).The answers that don't use
dos2unix
are even worse because they do naive search-and-replaces that will irreversibly corrupt binary files like executables, images and videos, and even the contents of the.git
directory.Both
dos2unix
andunix2dos
are ubiquitous, lightweight tools that have been pre-installed on every UNIX-based system I've ever used, meaning they're almost definitely already installed on your system. They also skip non-text files by default, making them safe to use on entire directories in this way unlike other answers.To convert all line endings to UNIX line endings (LF)
To convert all line endings to Windows line endings (CRLF)
The
-v
/--verbose
switch isn't required but will output which files are being converted to the console.这对我在 wsl2 上有用,将所有 java 文件从 CRLF 更改为 LF
This has worked for me on wsl2 to change all the java files from CRLF to LF
和其他的一样,但是用的是node.js
The same as the others but with node.js