BOMを含むAWK:正規表現を使用してUnicode BOMを処理するための素晴らしい方法はありますか?

BOMを含むAWK:正規表現を使用してUnicode BOMを処理するための素晴らしい方法はありますか?

UTF-8(BOMインクルード/除外)でエンコードされた2つのファイルがあります。

/tmp/bom$ ls
list.bom.txt  list.nobom.txt
/tmp/bom$ cat list.nobom.txt 
apple
banana
avocado
寿司
melon
/tmp/bom$ diff list.nobom.txt list.bom.txt 
1c1
< apple
---
> apple
/tmp/bom$ file list.nobom.txt list.bom.txt 
list.nobom.txt: UTF-8 Unicode text
list.bom.txt:   UTF-8 Unicode (with BOM) text

2つのファイルの唯一の違いはヘッダーBOMですEF BB BF

次に、「a」で始まる行をフィルタリングするために、キャレットを使用して短いawkスクリプトを作成しました。

/tmp/bom$ gawk '/^a.*/' list.nobom.txt
apple
avocado
/tmp/bom$ gawk '/^a.*/' list.bom.txt
avocado

残念ながら、ヘッダBOMの場合、apple最初の行は無視されます。

だから私の質問は次のようになりますこの問題を解決する方法はありますか?

私は3つの解決策を考えています。

  1. BOMバイトを直接作成します。例えば、

    gawk 'BEGIN { pat = "^(\xef\xbb\xbf)?a.*" } $0 ~ pat { print }'
    

    UTF-8で動作します。ただし、他のエンコーディングは処理しません。また、幅が0の切り捨て防止スペースとして使用されるU + FEFFがある場合、上記のスクリプトが失敗することもあります(説明を参照)。

  2. recodingを使用してBOMバイトを削除しますnkf。例えば、

    nkf --oc=UTF-8 list.bom.txt | gawk '/^a.*/'
    

    働くそれでも、もっと洗練された方法があるかどうかを知りたいです。

  3. [追加] これはbash機能を使用した最初の改善です。

    gawk -v bom="$(echo -e '\uFEFF')" '
        NR == 1 {
            pat = "^" bom;
            sub(pat, "")
        }
        /^a.*/ {
            print
        }
    '
    

    これは、BOMの有無にかかわらずUTF-8で動作します。しかし、これは私の環境のUTF-16では機能しません。したがって、2番目のオプションが優れています。

grepそして、これは正規表現マッチングsedや他のスクリプトを使用しても問題になると思います。したがって、一般的な解決策があればさらに感謝します。

答え1

UTF-8では、BOMは意味がありません。これは通常、Microsoftオペレーティングシステムの偽のソフトウェアのバグのために追加されます。

dos2unixこれは削除され、Windowsテキストファイルの他の属性が処理されます。

dos2unix < file.win.txt | awk ...

関連情報