在不使用dos2unix的情况下,递归地将目录及其子目录中所有文件的行尾符(dos->unix)转换为unix格式。

13
如何在没有dos2unix的情况下,递归地将目录和子目录中所有文件的EOL(dos->unix)转换为Unix格式?是否可以使用“tr -d '\r'”和管道来完成?如果可以,怎么做?
7个回答

14
对于当前目录中的所有文件,您可以使用一个Perl一行命令进行操作:perl -pi -e 's/\r\n/\n/g' *(从这里偷来的)。 编辑:通过一个小修改,您可以进行子目录递归。
find | xargs perl -pi -e 's/\r\n/\n/g'

2
如果您的 findxargs 支持它:find -print0 | xargs -0 ... 将处理带有空格的文件名。 - Dennis Williamson
6
在使用此命令时要注意Git仓库,从查找中排除.git子目录。 - prajmus

11

您可以使用sed的-i标志在原地更改文件:

find . -type f -exec sed -i 's/\x0d//g' {} \+

如果我是你,我会保留这些文件以确保操作正常完成。然后在完成后再删除临时文件。可以像这样完成:

find . -type f -exec sed -i'.OLD' 's/\x0d//g' {} \+
find . -type f -name '*.OLD' -delete

这应该处理包含空格的文件名。在每行末尾添加换行符不会导致文件变成双倍行距 - 或者甚至三倍行距(因为您正在用换行符替换回车符)吗?是的,我刚刚测试了一下。 - Dennis Williamson
@DennisWilliamson 我刚刚从办公室的一个脚本中轻松提取了这个。现在我在想那些脚本到底是如何工作的。(可能与它们旨在转换在Microsoft Office for Mac中创建的文件有关。)新版本应该可以正常工作。 - Tim Pote

2
您可以在批处理模式下使用编辑器。
find . -type f -exec bash -c 'echo -ne "%s/\\\r//\nx\n" | ex "{}" ' \;

这个解决方案是我在Mac OS X上唯一有效的。其他的都会遇到各种问题,比如“无法进行原地编辑:./lang不是常规文件,<>行22167。” - WilliamKF

2

您的文件名和目录名是否没有空格等非法字符?

如果是这样,那么这并不难。但如果您需要处理包含换行符和空格等任意字符的名称,则需要比这更加努力。

tmp=${TMPDIR:-/tmp}/crlf.$$
trap "rm -f $tmp.?; exit 1" 0 1 2 3 13 15

find . -type f -print |
while read name
do
    tr -d '\015' < $name > $tmp.1
    mv $tmp.1 $name
done

rm -f $tmp.?
trap 0
exit 0

陷阱功能确保您不会留下临时文件。您可以使用其他技巧,为您的临时文件名称添加更多随机性。除非您在敌对环境中工作,否则通常不需要这些技巧。请注意保留HTML标签。

请注意,tr 实际上识别 \r(BSD 和 GNU 变体),因此您可以使用 tr -d '\r' - Dietrich Epp

0

这将从当前目录和所有子目录中删除所有文件的回车符,并且应该在大多数类Unix操作系统上工作:

grep -lIUre '\r' | xargs sed -i 's/\r//'

0

如果\r后面没有跟着\n(在Tim Pote的文件中可能是这种情况):

  • 删除\r(使用tr -d)可能会删除换行符
  • \r替换为\n可能不会导致双重/三重换行符

也许Tim Pote可以验证他提到的文件上述观点。


这对我来说是对Tim Pote答案的良好评论,但它并没有很清楚地回答问题。 - Nikana Reklawyks

0
如果在Windows上完成:
尝试在Git Bash中运行命令:
$ find | xargs perl -pi -e 's/\r\n/\n/g'

它可以显示一些无法进行原地编辑:输入一条消息,然后忽略它


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