Linux 在没有 dos2unix 的情况下递归地转换目录和子目录中所有文件的所有 EOL(dos->unix)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10629231/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 06:22:07  来源:igfitidea点击:

Convert all EOL (dos->unix) of all files in a directory and sub-directories recursively without dos2unix

linuxbashunixcommand-lineend-of-line

提问by user1316233

How do I convert all EOL (dos->unix) of all files in a directory and sub-directories recursively withoutdos2unix? (I do not have it and cannot install it.)

如何在不递归的情况下转换目录和子目录中所有文件的所有 EOL(dos->unix)dos2unix?(我没有它,无法安装它。)

Is there a way to do it using tr -d '\r'and pipes? If so, how?

有没有办法使用tr -d '\r'和管道来做到这一点?如果是这样,如何?

回答by Tim Pote

You can use sed's -iflag to change the files in-place:

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

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

If I were you, I would keep the files around to make sure the operation went okay. Then you can delete the temporary files when you get done. This can be done like so:

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

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

回答by Jonathan Leffler

Do you have sane file names and directory names without spaces, etc in them?

你有没有空格等的合理文件名和目录名吗?

If so, it is not too hard. If you've got to deal with arbitrary names containing newlines and spaces, etc, then you have to work harder than this.

如果是这样,也不算太难。如果您必须处理包含换行符和空格等的任意名称,那么您必须比这更努力地工作。

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 '5' < $name > $tmp.1
    mv $tmp.1 $name
done

rm -f $tmp.?
trap 0
exit 0

The trap stuff ensures you don't get temporary files left around. There other tricks you can pull, with more random names for your temporary file names. You don't normally need them unless you work in a hostile environment.

陷阱内容可确保您不会留下临时文件。您还可以使用其他技巧,为临时文件名提供更多随机名称。除非您在恶劣的环境中工作,否则您通常不需要它们。

回答by smocking

For all files in current directory you can do it with a Perl one-liner: perl -pi -e 's/\r\n/\n/g' *(stolen from here)

对于当前目录中的所有文件,您可以使用 Perl one-liner 来完成:(perl -pi -e 's/\r\n/\n/g' *这里窃取)

EDIT: And with a small modification you can do subdirectory recursion:

编辑:通过一个小的修改,你可以做子目录递归:

find | xargs perl -pi -e 's/\r\n/\n/g'

回答by pizza

You can also use the editor in batch mode.

您还可以在批处理模式下使用编辑器。

find . -type f -exec bash -c 'echo -ne "%s/\\r//\nx\n" | ex "{}" ' \;

回答by Line App Maker

If \risn't followed by \n(maybe the case in files of Tim Pote):

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

  • deleting \r(using tr -d) may remove newlines
  • replacing \rwith \nmay not cause double / triple newlines
  • 删除\r(使用tr -d)可能会删除换行符
  • 替换\rwith\n可能不会导致双/三换行

Maybe Tim Pote could verify the points above for the files he mentioned.

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

回答by Tony

This removes carriage returns from all files in the current directory and all subdirectories, and should work on most Unix-like OSs:

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

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