ソースファイルの各行の先頭には特殊文字があります。ファイルは二重スペースで区切られます。
サンプルデータファイル:
â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)は、latin1
iso8859-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ロケールを使用する文字)を削除する必要があります。