各行の最初の文字を特殊文字として削除し、ファイルをセミコロンで区切られたファイルに変換したいと思います。

各行の最初の文字を特殊文字として削除し、ファイルをセミコロンで区切られたファイルに変換したいと思います。

ソースファイルの各行の先頭には特殊文字があります。ファイルは二重スペースで区切られます。

サンプルデータファイル:

âNAME  ABC
âAGE  21
âADDRESS  XYZ street ABC city
âCONTACT  13244235
âDOJ  20181212

â各行の最初の特殊文字を削除し、ファイルを;(セミコロン)区切りファイルに変換したいと思います。

私が書いた後、コードはUATではうまくいきますが、PRODではうまくいきません。

awk '{ print substr($0,1) }' FILE1.txt | sed 's/ /;/' > FILE2.txt

UAT出力(予想される予測出力):

NAME;ABC
AGE;21
ADDRESS;XYZ street ABC city
CONTACT;13244235
DOJ;20181212

製品出力:

âNAME;ABC
âAGE;21
âADDRESS;XYZ street ABC city
âCONTACT;13244235
âDOJ;20181212

同じコードはUATでうまく機能します。つまり、最初の文字を削除してファイルをセミコロンで区切られたファイルに;変換しますが、PRODは最初の特殊文字を削除せずにファイルをセミコロンで区切られたファイルに変換します。

出力locale

locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

誰でもこの問題を解決するのに役立ちますか?

答え1

あなたの問題が文字エンコーディングに関連している可能性があると思います。FILE1.txt両方の環境で表示してみてください。

hexdump -C FILE1.txt

E-asciiまたはUTF-8でエンコードできます(参照:https://en.wikipedia.org/wiki/%C3%82#Character_mappings)

問題を解決するには、両方のエンコーディングを一致させてください。

        â in UTF-8                     â in other encoding
        |                              |
        v                              v
sed 's/\xc3\xa2//' FILE1.txt | sed 's/\xE2//' > FILE2.txt

別の回避策は、ファイルを処理する前に既知のエンコーディングに変換することです。

PRODエンコーディングをテストしないと危険です。

答え2

â見ている内容は、エンコーディングの問題がほぼ確実であり、すべての行が大文字で始まる必要があると仮定しているため、次のことを試すことができます。

LC_ALL=C sed 's/^[^A-Z]*//; s/   */;/g' FILE1.txt > FILE2

これにより、AZ範囲にC文字が含まれないようにするロケールを使用してコマンドが実行されます。âその後、sedコマンドは、AZの範囲内にない各行の先頭からすべての文字を削除し、2つ以上のスペースを持つすべてのエントリを;

答え3

努力する

sed 's/^â//; s/   */;/g' FILE1.txt > FILE2.txt

うまくいかなかったら反対投票をしてください。

答え4

各行の最初の文字を削除するには、次のようにする必要があります。

cut -c2- # not with the GNU implementation which is currently not multi-byte aware
sed 's/^.//'
awk '{print substr($0, 2)}' # note the 2 instead of 1 as offsets are 1-based
                            # not with mawk or other non-multi-byte aware awk
                            # implementations.

.ただし、このâ文字を一致させてsubstr()正しく機能させるには、âロケールエンコーディングに従ってエンコードする必要があります(出力を参照locale charmap)。

最初の文字を削除し、すべてのスペースシーケンスをその文字に置き換えるには、;次のようにします。

sed 's/^.//;s/[[:space:]]\{1,\}/;/g'

または:

awk -v OFS=';' '{$0 = substr($0, 2); $1 = $1; print}'

(ただし、後者には;空白文字で終わる末尾の行は含まれておらず、区切り文字と見なされる空白文字のリストはawk実装とロケールによって異なります.)

これでâ(U + 00E2)は、latin1iso8859-1文字セット(別のシングルバイト文字セットとも呼ばれます)でバイト0xe2にエンコードされます。また、対応するバイト0xe2は、複数のUnicode空白文字(U + 2000からU + 200Bまでの空白文字など)を含む複数の3バイトUTF-8文字エンコーディングの最初のバイトでもあります。

したがって、latin1端末に表示される場合、â入力には実際にはU + 2002(EN SPACE)を含めることができます(例:UTF-8(0xe2 0x80 0x82)でエンコードされている)。ターミナルはこれを0x80と0x820xe2と表示せずに表示します。âlatin1ではありません。

EN SPACEを削除するには、UTF-8ロケールで1文字または1バイトのロケール3文字(latin1またはCロケールを使用する文字)を削除する必要があります。

関連情報