linux - 递归地从目录中的文件中删除 '\r' 字符

标签 linux windows bash git

我在 Windows 10 机器上编写代码,将其上传到实际运行代码的远程 Linux 机器上。通常使用类似 Jetbrains upload 的 IDE 功能或 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"

这个错误和我目前的解决方法相当烦人。我尝试使用包含在 ~/mytools/remove_win_char.sh 的 $PATH 中的以下 bash 脚本对其进行自动化

#!/usr/bin/bash

find . -type f -exec sed -i 's/\r//g' {} \;

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

$ 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 行结尾的 text 文件,然后相应地处理文件:

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,然后是 CR/LF- to-LF-fixed 使用 dos2unix

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

关于linux - 递归地从目录中的文件中删除 '\r' 字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65333813/

相关文章:

linux - 如何在 Perl 中将文件拆分为给定数量的部分? (在 Unix 上)

linux - linux shell 管道是流水线吗?

bash - Linux Shell脚本和递归,变量不保留值

c - memfd_secret() : how is it supposed to work?

linux - 使用 -n 替换后的空白 sed 输出

windows - 具有不可重定向输出的实用程序 (Windows)

windows - 最喜欢的 Windows 键盘快捷键

windows - COM 如何通过后期绑定(bind)查找并运行 DLL?

linux - "Must be connected to a terminal error"在 Linux 容器上使用 screen -x 命令

linux - 创建目录结构的 Bash 脚本