각 줄의 첫 번째 문자를 특수 문자로 제거하고 파일을 세미콜론으로 구분된 파일로 변환하고 싶습니다.

각 줄의 첫 번째 문자를 특수 문자로 제거하고 파일을 세미콜론으로 구분된 파일로 변환하고 싶습니다.

소스 파일의 각 줄 시작 부분에는 특수 문자가 있습니다. 파일은 이중 공백으로 구분됩니다.

샘플 데이터 파일:

â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 범위에 없는 각 줄의 시작 부분에서 모든 문자를 제거한 다음 두 개 이상의 공백이 있는 모든 항목을 ;.

답변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는 여러 유니코드 공백 문자(예: U+2000 ~ U+200B 공백 문자)를 포함하여 여러 3바이트 UTF-8 문자 인코딩의 첫 번째 바이트이기도 합니다.

따라서 latin1 터미널에 표시되는 경우 â입력에는 실제로 U+2002(EN SPACE)가 포함될 수 있습니다(예: UTF-8(0xe2 0x80 0x82)으로 인코딩됨). 터미널에서는 이를 0x80 및 0x82 0xe2로 표시하지 않고 표시합니다. âlatin1이 아닙니다.

EN SPACE를 제거하려면 UTF-8 로케일로 문자 1개 또는 단일 바이트 로케일 문자 3개(예: latin1 또는 C 로케일을 사용하는 문자)를 제거해야 합니다.

관련 정보