如何递归地在目录中搜索并删除所有文件中的^M?

7

在Windows中编辑的文件末行会有M^。我该如何去除它们?


2
See last word in headline. - Cyrus
@amdixon 我没有安装dos2unix,并且也不会/不能安装。 - maan81
@PaulR 我无法在文本编辑器中完成它,因为我需要检查一个完整的项目,这意味着成千上万个文件。手动浏览每个文件/目录是不明智的。 - maan81
@maan81:如果你有一个不错的文本编辑器,那么你可以直接将其指向一个目录,并告诉它递归地进行全局搜索和替换——我经常用BBEdit做这个——我相信Linux上也一定有类似功能的编辑器。再次强调,这并不是一个编程问题,所以它不适合在StackOverflow上讨论。 - Paul R
@maan81:是的,当你提问时,明确你需要什么总是很重要 - 这样可以节省大家的时间和精力。 - Paul R
显示剩余3条评论
1个回答

19

注意

使用此命令时要非常小心,因为它将替换所有的LF/CR字符序列,而不考虑其位置或上下文。在处理二进制文件或具有特殊配置格式的文件时要格外小心。带有git子模块的目录就是一个例子,因为字符序列已经被存储为持久提交。

这是用于回车控制的控制代码。Windows使用LF/CR表示法作为行分隔符,而UNIX系统仅使用LF。

以下命令将对相对于当前目录向下递归遍历整个文件系统树中的所有文件执行此操作。

find . -type f | xargs -Ix sed -i.bak -r 's/\r//g' x

上面的代码将自动生成备份文件(文件名后缀为.bak)。

一旦确认文件没有问题,使用以下代码来删除备份文件。

find . -type f -name '*.bak' | xargs -Ix rm x

1
@Cyrus 感谢您指出这一点,我已经更改为在 sed 中使用 -i 选项。 - nehcsivart
3
如果目录内包含 Git 子模块,请勿使用此命令。 - Alex Bender
好的,我做了... 我不得不替换超过20000个文件。方法如下:find -iname \*.* | rename -v -f "s/\.bak//g"。没有任何损失,希望对你有帮助。 - Paolo
1
@Paolo 我已经在顶部添加了一条关于此事的注释。 - nehcsivart
@AaronFranke 是的,你可以忽略 .git 目录的几种方法。一种方法是显式列出你想要包含的目录(例如 find a/ b/ -type f ... 或者甚至是 find * -type f ...,前提是你的 shell 不会将 * 展开成隐藏文件,而且你没有自己的隐藏文件)。我相信 find 还有一些标志可以忽略某些模式,比如 -regex 标志。 - nehcsivart
显示剩余6条评论

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