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

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

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

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

â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 文字を削除する必要があります。

関連情報