以递归方式从目录中的文件中删除"\r"字符



我在Windows 10机器上编写代码,并将其上传到实际运行的远程Linux机器上。通常使用IDE功能,如Jetbrains上传或WinSCP。我还远程进行所有版本控制,通常使用以下工作流程:

(in remote session)
1. $ git clone git@github.com:myorg/myrepo.git
(in local)
2. Download from remote: /myrepo -> C://User/Me/myrepo
3. Edit some_file.py
4. Upload to remote: C://User/Me/myrepo/some_file.py -> /myrepo/some_file.py
(in remote session)
5. $ python some_file.py  # ERROR: something about bad chars or line endings with 'r'
6. $ sed -i 's/r//' some_file.py; python some_file.py  # WORKS!
7. $ git add some_file.py; git commit -m "removed bad win char"

这个错误和我目前的解决方法相当烦人。我试着用下面的bash脚本将其自动化,该脚本包含在我的$PATH中,位于~/mytools/remove_win_char.sh

#!/usr/bin/bash
find . -type f -exec sed -i 's/r//g' {} ;

不幸的是,这在git repos中有一些意想不到的副作用:(即,这个答案不起作用(

$ remove_win_char.sh
$ git status
fatal: unknown index entry format 0x2f610000

我试图通过在脚本中只指定某些文件来修复:

find . -name *.py -o -name *.sql -o -name *.sh -exec sed -i 's/r//g' {} ;

不幸的是,这似乎只影响了.sh文件。

有人知道如何仅使用find过滤.py.sql.sh文件吗?或者知道删除这些由Windows本地创建的r字符的更好方法吗?

使用findsed可能会破坏您的存储库,因为它们不知道git存储库、其内部结构以及git处理跟踪文件的方式。您必须使用git ls-files来生成它跟踪的文件列表,这些文件是以CR/LF行结尾的文本文件,然后相应地处理这些文件:

git ls-files --eol

它产生类似的表格输出

i/lf    w/lf    attr/                   .gitignore
i/crlf  w/crlf  attr/                   README.md
i/lf    w/lf    attr/                   env/install.sh

可以使用awk(不幸的是,不确定grep是否可以处理字段(和cut进行过滤,然后使用dos2unix固定CR/LF到LF。

git -c core.quotepath=off ls-files --eol '*.py' '*.sql' '*.sh'  # query git
| awk '$1 ~ /^i/crlf/'                                     # filter only lines starting with i/crlf
| cut -f2                                                   # filter files only (see why it is TAB-delimited https://git-scm.com/docs/git-ls-files#_output)
| xargs -I{} dos2unix {}                                     # convert CR/LF to LF

最新更新