![如何计算 UTF-16LE/CR-LF/BOM 文件中的行数?](https://linux22.com/image/43282/%E5%A6%82%E4%BD%95%E8%AE%A1%E7%AE%97%20UTF-16LE%2FCR-LF%2FBOM%20%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E8%A1%8C%E6%95%B0%EF%BC%9F.png)
最直接的想法是wc
,但下一个不太直接的想法是... *nixwc
纯粹是用于 *nix 行结尾 \x0a 吗?... 看起来是这样。
我已经解决了这个问题,但我觉得可能/必须有一种比处理原始文件的十六进制转储更简单的方法。
这是我的版本,但计数中仍然存在神秘的差异。 wc
报告 1比此脚本的+0a
的总和多。 CRLF
0a
file="nagaricb.nag"
echo Report on CR and LF in UTF-16LE/CR-LF
echo =====================================
cat "$file" | # a useles comment, courtesy of cat
xxd -p -c 2 |
sed -nr '
/0a../{
/0a00/!{
i ‾‾`0a: embedded in non-newline chars
b
}
}
/0d../{
/0d00/!{
i ‾‾`0d: embedded in non-newline chars
b
}
}
/0a00/{
i ‾‾`CR: found stray 0a00
b
}
/0d00/{
N
/0d00\n0a00/{
i ‾‾`CRLF: found as normal newline pairs
b
}
i ‾‾`LF: found stray 0d00
}' |
sort |
uniq -c
echo " ====="
printf ' %s ‾‾`wc\n' $(<"$file" wc -l)
输出
Report on CR and LF in UTF-16LE/CR-LF
=====================================
125 ‾‾`0a: embedded in non-newline chars
407 ‾‾`0d: embedded in non-newline chars
31826 ‾‾`CRLF: found as normal newline pairs
=====
31952 ‾‾`wc
有没有一些更标准/简单的方法来做到这一点?
答案1
我会将文件转换为带有 LF 行结尾的 UTF-8,这样我就可以直接使用本机工具:
$ iconv -f UTF-16LE -t UTF-8 myfile.txt | dos2unix | wc -l
这dos2unix
部分是最棘手的部分。该工具有许多变体,但并非所有变体都知道如何在管道中使用。有时它也被称为其他名称,例如d2u
.
答案2
下面是一个 perl 脚本,它以 UTF-16(通过 BOM 检测到字节顺序)打开文件(作为命令行参数给出),并计算行数。
#! /usr/bin/env perl
use strict;
use warnings;
while (my $file = shift @ARGV) {
my $fh;
if (!open($fh, '<:encoding(UTF-16)', $file)) {
print STDERR "Failed to open [$file]: $!\n";
next;
}
my $count = 0;
$count++ while (<$fh>);
print "$file: $count\n";
close $fh;
}
(如果不理解 BOM,则死亡。)
答案3
如果您的 dos2unix 版本 >= 7.1,您可以使用 -i 选项来获取有关换行符数量的信息。还支持 UTF-16 文件。当文件有 BOM 时,dos2unix 自动检测它是 UTF-16、LE 或 BE。当文件没有 BOM 时,您可以使用选项 -ul 来告诉它是 UTF-16LE(或 -ub 表示 UTF-16BE)。
dos2unix -i 将按顺序打印 DOS、Unix 和 Mac 换行符的数量。示例(带 BOM):
$ dos2unix -i utf16le.txt
50 0 0 UTF-16LE text utf16le.txt
无物料清单:
$ dos2unix -ul -i utf16len.txt
50 0 0 no_bom text utf16len.txt
请参阅手册了解更多信息。