有没有办法快速识别带有 Windows 或 Unix 行终止的文件?

有没有办法快速识别带有 Windows 或 Unix 行终止的文件?

我知道我们可以使用dos2unix在 Windows 和 Unix 行终止符之间进行转换。我想知道是否有任何命令可以告诉我文件是否有 Windows 或 Unix 行终止符?

答案1

$ file f1 f2 f3
f1: ASCII text, with CRLF, LF line terminators
f2: ASCII text, with CRLF line terminators
f3: ASCII text

如果您觉得有必要检查文件中的每一行,您可以这样做:

$ grep -c "^M" f1 f2
f1:0
f2:3

$ wc -l f1 f2
 3 f1
 3 f2
 6 total

“^M” 是使用Ctrl++输入V CtrlM,是 ASCII 回车符 (CR)。

这里我们看到文件 f1 有三行但没有 CR,因此所有行尾都必须是 Unix 风格的单独 LF。

文件 f2 具有相同数量的行和 CR,因此可以合理地猜测它使用 MS-DOS 和 Windows 所使用的 CR、LF 行尾。

答案2

在 Windows 上,一种快速的方法是使用记事本打开文件。记事本将仅在 Windows 样式终止符 (CR+LF) 上显示换行符,而不会在 Unix 终止符 (LF) 上显示换行符。因此,您的 Unix 文本将如下所示:

Line1Line2Line3Line4

而 Windows 文本将如下所示:

line1
line2
line3
line4

我不太熟悉 unix/linux 平台,但我确信您可以使用 gedit 或 emacs 等程序进行类似的破解。

答案3

c=($(perl -0777ne 'print $_ =~ tr/\n//; print " "; 
                    print $_ =~ tr/\r//;'))
if   ((!(c[0] +   c[1]))) ;then echo no line endings  
elif ((  c[0] && !c[1] )) ;then echo LF
elif (( !c[0] &&  c[1] )) ;then echo CR 
elif ((  c[0] ==  c[1] )) ;then echo CRLF 
else echo "ambiguous LF ${c[0]} CR ${c[1]}"
fi

请注意,为了提高速度,只计算单个\rs 和s,但如果文件中包含两种类型的数量相等,而且又不是 Windows CRLF 文件,那将是一个非常古怪的文件...\n

还请注意,*nix 工具file不会对文件进行完整扫描,而此perl脚本会。您尚未提及希望它在哪个平台上运行;我已使用bash脚本来测试 perl 的输出,但可以将其更改为 Windowcmd脚本。

您只需将您的文件通过管道传输给它即可。

答案4

PowerShell 内置于 Windows,并且可用于所有其他主要的 平台所以你可以用它来检测这样的格式

('LF', 'CRLF')[([regex]::Matches($(gc -Ra path\to\file.txt), "\r?\n") | group -P Length).Group[0].Value.Length - 1]

如果你想让它适用于混合 CRLF 文件,那么你需要使用下面更完整的解决方案

$content = Get-Content -Raw path\to\file.txt
[regex]::Matches($content, "\r?\n") | Group-Object -Property Length `
    | Tee-Object -Variable newlines
if ($newlines.Length -eq 2) {
    echo "Mixed CRLF"
} else {
    if ($newlines[0].Group[0].Value.Length -eq 2) {
        echo "CRLF"
    } else {
        echo "LF"
    }
}

另请注意,我假设只有 CRLF 和 LF,就像 git 的行为一样。要使其适用于 CR 文件,您需要进行一些小的更改

另一个解决方案:

$content = Get-Content -Raw -Encoding Byte .\path\to\file.txt
$cr = 0; $lf = 0
foreach ($c in $content) { if ($c -eq 10) { $lf++ } elseif ($c -eq 13) { $cr++ } }
echo "CR = $cr, LF = $lf"

相关内容