
ソース ファイルの各行の先頭に特殊文字があります。ファイルはダブル スペースで区切られています。
サンプルデータファイル:
â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
PROD出力:
â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
両方のenvで表示してみてください。
hexdump -C FILE1.txt
E-asciiまたはUTF-8でコード化できます(https://en.wikipedia.org/wiki/%C3%82#キャラクターマッピング)
問題を解決するには、両方のエンコーディングを一致させてみます。
â 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
これにより、ロケールを使用してコマンドが実行され、C
入力した文字が AZ の範囲に含まれないことが保証されますâ
。次に、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) は、iso8859-1 文字セット (別名latin1
および他のいくつかの 1 バイト文字セット) ではバイト 0xe2 としてエンコードされることにも注意してください。また、バイト 0xe2 は、いくつかの 3 バイト UTF-8 文字のエンコードの最初のバイトでもあり、その中にはいくつかの Unicode 空白文字 (U+2000 から U+200B のスペース文字など) が含まれています。
したがって、â
latin1 ターミナルに が表示されている場合は、入力に実際には U+2002 (EN SPACE) が含まれており、たとえば UTF-8 (0xe2 0x80 0x82) でエンコードされている可能性があります。ターミナルには0xe2
と表示されâ
、latin1 にない 0x80 と 0x82 については何も表示されません。
EN SPACE を削除するには、UTF-8 ロケールで 1 文字を削除するか、シングルバイト ロケール (latin1 または C ロケールを使用するロケールなど) で 3 文字を削除する必要があります。