如何确定文件的行尾符

53

我有一堆(数百个)文件,应该具有Unix行结尾。 我强烈怀疑其中一些具有Windows行结尾,并且我想通过编程找出哪些需要更改。

我知道我可以在脚本中运行

flip -u
或类似的命令来转换所有内容,但我想先识别那些需要更改的文件。

7个回答

72

您可以使用file工具,它会告诉您行尾的类型。或者,您可以直接使用dos2unix -U命令将所有行尾转换为Unix格式,无论原来的格式是什么。


5
文件没有显示行尾符。例如:"file .bashrc => .bashrc: ASCII English text" 需要一些额外的键吗? - Fedir RYKHTIK
10
是的,它可以,只是如果文件有常规的LF行结尾,那么它不会输出任何内容。但是如果文件具有CRLF、裸CR或混合行尾,则会告诉你这一点。 - Adam Rosenfield
2
在我的OS X上,对于一个仅包含CRLF的Perl脚本没有起作用。可能是GNU扩展? - Tim Yates
3
这适用于某些文件类型,但不适用于其他文件类型。在Linux上,例如对于HTML文件,它不会报告行尾符。 - Edward Anderson
“file foo.txt” 在 OS X 10.9 上运行良好。它打印出“foo.txt:ASCII文本,带有CRLF行终止符”。 - Bogdan Calmac
差不多10年后,值得一提的是dos2unix功能有-i选项来获取文件信息。我发现这是最可靠的识别罪犯的方法。这也在https://unix.stackexchange.com/a/231408/17800中有所描述。 - ikaerom

29

你可以使用grep

egrep -l $'\r'\$ *

3
不知为何,当我在MacOS X shell中运行此命令时,我会得到该目录中所有文件的列表,即使其中包括我使用“echo“test”>torderform6.cpp”新生成的文件。你有什么想法,可能出了什么问题? - Adrian Grigore
7
在Ubuntu上,它只是为我列出文件夹中的所有文件。 - rjmunro
2
这个命令仍然会列出已经运行了dos2unix的文件。 - Phyxx
这里是关于'$'前缀字符串在脚本中的含义的解释:http://unix.stackexchange.com/questions/48106/what-does-it-mean-to-have-a-dollarsign-prefixed-string-in-a-script - Bryce Guinta
使用 $(echo -e '\r') 如果无法让 Bash 为您执行 ASCII 扩展(将 $'\r' 替换为它)。 - Bryce Guinta
1
在 Mac 上我使用以下命令:grep -E -rl '\r' . - LanDenLabs

14

类似于以下内容:

perl -p -e 's[\r\n][WIN\n]; s[(?<!WIN)\n][UNIX\n]; s[\r][MAC\n];' FILENAME

虽然那个正则表达式可能需要一些精细化和整理。

这将输出你的文件,并在每行结尾加上WIN、MAC或UNIX。如果你的文件有混合的换行符(或者差异),是个很好的工具来处理这种可怕的混乱。


在Ubuntu上对我有用,所接受的答案似乎只列出了所有文件。 - Noel Kennedy
对我不起作用,显示:Unmatched ) in regex; marked by <-- HERE in m/(?&lt;!WIN) <-- HERE \n/ at -e line 1. - moshen
您需要将<替换为< - Joseph
“<”符号在之前的编辑中出了问题,现在我已经修复了它。 - Cheran Shunmugavel

5

这是最保险的答案。Stimms的回答没有考虑子目录和二进制文件。

find . -type f -exec file {} \; | grep "CRLF" | awk -F ':' '{ print $1 }'
  • 使用file命令查找文件类型。带有CRLF的文件具有Windows回车符号。 file命令的输出以冒号:分隔,第一个字段是文件的路径。

确实是最可靠的方法。只需运行 find . -type f -exec file {} \; | grep "CRLF" | awk -F ':' '{ print $1 }' | xargs flip -ub 即可仅转换所有找到的文件。 - pixelbrackets
3
它并不是最可靠的 -- file 命令在输出中并不总是能够准确地指出" CRLF ",这取决于文件类型。我发现,在包含类似纯文本文件的文本的 SVG 文件中,file 命令没有提到使用的行结束符类型。因此,这个脚本并不是文件类型无关的。只是说一下。除此之外,这个单行命令看起来很合理,尽管前面所述的限制还存在。 - Armen Michaeli

2

Unix使用一个字节,0x0A(换行符),而Windows使用两个字节,0x0D 0x0A(回车符,换行符)。

如果你从未看到0x0D,则很可能是Unix。如果你看到0x0D 0x0A对,则很可能是MS-DOS。


0

当您知道哪些文件具有 Windows 行尾 (0x0D 0x0A\r \n) 后,您会对这些文件做什么?我想,您会将它们转换为 Unix 行尾 (0x0A\n)。您可以使用 sed 工具将带有 Windows 行尾的文件转换为 Unix 行尾,只需使用以下命令:

$> sed -i 's/\r//' my_file_with_win_line_endings.txt

你可以像这样将它放入脚本中:
#!/bin/bash

function travers()
{
    for file in $(ls); do
        if [ -f "${file}" ]; then
            sed -i 's/\r//' "${file}"
        elif [ -d "${file}" ]; then
            cd "${file}"
            travers
            cd ..
        fi
    done
}

travers

如果你在根目录下运行它并处理文件,最终你将确保所有文件都是使用 Unix 换行符。


0

Windows使用字符13和10作为行尾,Unix只使用其中一个(我不记得是哪一个)。因此,您可以将字符13和10替换为字符13或10(使用Unix的那个)。


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