UTF-16LE/CR-LF/BOMファイルの行数をどのように計算しますか?

UTF-16LE/CR-LF/BOMファイルの行数をどのように計算しますか?

最も即時のアイデアはですwcが、次にあまり直接的なアイデアは... *nixwcは純粋に *nix ラインエンド \x0a? だけのためのものです。 ...そうですね。

私はこの問題を解決しましたが、元のファイルの16進ダンプを処理するよりも簡単な方法があるかもしれません。

これは私のバージョンですが、数にはまだ不思議な違いがあります。 wcこのスクリプトの+の合計よりも多くの1を報告します0aCRLF0a

 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

以下は、UTF-16(BOMによって検出されたバイト順)でファイル(コマンドライン引数として提供されている)を開き、行数を計算するPerlスクリプトです。

#! /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(またはUTF-16BEの場合は-ub)であることを通知できます。

dos2unix -i は、DOS、Unix、Mac 改行文字の数を順番に出力します。はい(BOMを含む):

$ dos2unix -i utf16le.txt
      50       0       0  UTF-16LE  text    utf16le.txt

BOMなし:

$ dos2unix -ul -i utf16len.txt
      50       0       0  no_bom    text    utf16len.txt

詳しくはマニュアルをご覧ください。

関連情報